what is the actual difference between &Struct{field: "blabla"} and Struct{field: "blabla"} (without memory address symbol)?

huangapple go评论70阅读模式
英文:

what is the actual difference between &Struct{field: "blabla"} and Struct{field: "blabla"} (without memory address symbol)?

问题

package main

import "fmt"

type rabbit struct {
	food string
}

func (r *rabbit) test() {
	fmt.Println(r.food)
}

func main() {
	roger := &rabbit{"carrot"} //rabbit{"carrot"}也可以实现相同的效果
	roger.food = "salad"
	roger.test()
}

无论你将roger定义为&rabbit{"carrot"}还是rabbit{"carrot"},你都可以更改其属性并调用指针接收器。但是,如果你必须像这个例子中一样实现一个接口:

package main

import "fmt"

type interfaccia interface {
	test()
}

type rabbit struct {
	food string
}

func (r *rabbit) test() {
	fmt.Println(r.food)
}

func someFunc(elemento interfaccia) {
	elemento.test()
}

func main() {
	roger := &rabbit{"carrot"} //如果没有指针接收器,你将会遇到错误
	someFunc(roger)
}

那么由于接口的原因,你必须将roger设置为指针接收器。如果我有一个递归结构体,像这样:

type rabbit struct {
	food       string
	girlfriend *rabbit
}

那么我总是被迫使用指针。

我的疑问是:既然&rabbit{"carrot"}包含了rabbit{"carrot"}的所有内容,为什么我要使用后者?

英文:

i.e.

package main

import "fmt"

type rabbit struct {
	food string
}

func (r *rabbit) test() {
	fmt.Println(r.food)
}

func main() {
	roger := &rabbit{"carrot"} //rabbit{"carrot"} would have done the same thing
	roger.food = "salad"
	roger.test()
}

whether you define roger as &rabbit{"carrot"} or rabbit{"carrot"}, you can in any case change its attributes and call pointer receivers. But if you had to implement an interface like in this example

package main

import "fmt"

type interfaccia interface {
	test()
}

type rabbit struct {
	food string
}

func (r *rabbit) test() {
	fmt.Println(r.food)
}
func someFunc(elemento interfaccia) {
	elemento.test()
}

func main() {
	roger := &rabbit{"carrot"} //without pointer receiver you would bump into an error
	someFunc(roger)

}

then you are forced to set roger as pointer receiver due to the interface. and if I had a recursive struct like this:

type rabbit struct {
	food       string
	girlfriend *rabbit
}

then I'm always forced to use the pointer.

My concern is: since &rabbit{"carrot"} includes all things of rabbit{"carrot"}, why should I use the last one?

答案1

得分: 2

一种类型的方法可以使用指针接收器或值接收器。当该类型实现一个接口时,使用指针接收器和值接收器的方法之间存在一个注意事项。

如果一个类型使用值接收器实现了接口的所有方法,那么在将该类型分配给接口变量或传递给接受该接口作为参数的函数时,该类型的值和指针都可以使用。

如果一个类型使用指针接收器实现了接口的所有方法,那么只能使用该类型的指针将其分配给接口变量或传递给接受该接口作为参数的函数。

在Go Tour中可以看到一个例子,点击这里

英文:

A method of a type can either have a pointer receiver or a value receiver. There is a caveat while pointer vs value receiver for methods of a type when that type implements an interface

If a type implements all methods of an interface using value receiver, then both value and pointer of that type can be used while assigning to that interface variable or while passing to a function which accept an argument as that interface.

If a type implements all methods of an interface using pointer receiver, then the only pointer of that type can be used while assigning to that interface variable or while passing to a function that accepts an argument as that interface.

see the example in go tour here

huangapple
  • 本文由 发表于 2021年8月4日 17:51:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/68649126.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定