*(指针符号)在以下 Go 方法中有何不同?
What different does the * (pointer symbol) makes in the following Go method?
我正在学习本教程:https://github.com/astaxie/build-web-application-with-golang/blob/master/en/02.5.md。
我仍然不太理解指针,所以过去让我有点困惑:func (h *Human) SayHi()
。我尝试删除 *
并且输出结果完全相同。为什么在这种情况下 *
是必要的?有人可以用下面的代码给我一个不同输出的例子吗?
package main
import "fmt"
type Human struct {
name string
age int
phone string
}
type Student struct {
Human // anonymous field
school string
}
type Employee struct {
Human
company string
}
// define a method in Human
func (h *Human) SayHi() {
fmt.Printf("Hi, I am %s you can call me on %s\n", h.name, h.phone)
}
func main() {
mark := Student{Human{"Mark", 25, "222-222-YYYY"}, "MIT"}
sam := Employee{Human{"Sam", 45, "111-888-XXXX"}, "Golang Inc"}
mark.SayHi()
sam.SayHi()
}
它的不同之处在于,该方法将定义在指向 Human
结构的指针上,并且该结构中的所有方法随后将对指向的值进行操作。
如果您要松开 *
,该方法将对您调用该方法的结构的副本进行操作,因此您对该方法中的结构所做的任何写入对于调用方法的代码。
由于方法体只执行一个fmt.Printf
并打印一些值,所以方法是否定义在指针上并没有太大的区别。
在某些情况下,为了并发安全,您最好不要在指针上定义方法,因为这可能会导致同时访问和写入底层结构值。
使用指针接收器有两个原因:
- 首先,避免在每次方法调用时复制值,如果值类型是大型结构,效率会更高)。
- 其次,该方法可以修改其接收者指向的值。
因此在您的示例中,如果您再添加一种转储方法来更改 phone,如下所示:
func (h Human) ChangePhone() {
h.phone = 'whatever'
}
调用此方法后phone不会改变,这就是*
点发挥作用的原因。
我正在学习本教程:https://github.com/astaxie/build-web-application-with-golang/blob/master/en/02.5.md。
我仍然不太理解指针,所以过去让我有点困惑:func (h *Human) SayHi()
。我尝试删除 *
并且输出结果完全相同。为什么在这种情况下 *
是必要的?有人可以用下面的代码给我一个不同输出的例子吗?
package main
import "fmt"
type Human struct {
name string
age int
phone string
}
type Student struct {
Human // anonymous field
school string
}
type Employee struct {
Human
company string
}
// define a method in Human
func (h *Human) SayHi() {
fmt.Printf("Hi, I am %s you can call me on %s\n", h.name, h.phone)
}
func main() {
mark := Student{Human{"Mark", 25, "222-222-YYYY"}, "MIT"}
sam := Employee{Human{"Sam", 45, "111-888-XXXX"}, "Golang Inc"}
mark.SayHi()
sam.SayHi()
}
它的不同之处在于,该方法将定义在指向 Human
结构的指针上,并且该结构中的所有方法随后将对指向的值进行操作。
如果您要松开 *
,该方法将对您调用该方法的结构的副本进行操作,因此您对该方法中的结构所做的任何写入对于调用方法的代码。
由于方法体只执行一个fmt.Printf
并打印一些值,所以方法是否定义在指针上并没有太大的区别。
在某些情况下,为了并发安全,您最好不要在指针上定义方法,因为这可能会导致同时访问和写入底层结构值。
使用指针接收器有两个原因:
- 首先,避免在每次方法调用时复制值,如果值类型是大型结构,效率会更高)。
- 其次,该方法可以修改其接收者指向的值。
因此在您的示例中,如果您再添加一种转储方法来更改 phone,如下所示:
func (h Human) ChangePhone() {
h.phone = 'whatever'
}
调用此方法后phone不会改变,这就是*
点发挥作用的原因。