有一个简单的 struct ,如下所示:

type Event struct {
    Id         int
    Name       string
}

这两种初始化方法有什么不同?

e1 := Event{Id: 1, Name: "event 1"}
e2 := &Event{Id: 2, Name: "event 2"}

为什么我要使用这两种初始化方法中的任何一种?

推荐答案

第一种方法

e1 := Event{Id: 1, Name: "event 1"}

正在将变量e1初始化为类型为Event的值.

第二个

e2 := &Event{Id: 1, Name: "event1"}

is initializing e2 as a pointer to a value of type Event As you stated in the comments, the set of methods defined on a value of a given type are a subset of the set of methods defined on a pointer to a value of that type. This means that if you have a method

func (e Event) GetName() string {
    return e.Name
}

那么e1e2都可以调用这个方法,但是如果您有另一个方法,比如:

func (e *Event) ChangeName(s string) {
    e.Name = s
}

然后e1不能使用ChangeName方法,而e2是.

This (100 is not able to use the 101 method, while 102 is) is not the case (although it may have been at the time of writing for this help), thanks to @DannyChen for bringing this up and @GilbertNwaiwu for testing and posting in the comments below.

(为了解决上面划掉的部分:在 struct 类型上定义的方法集由为该类型定义的方法和指向该类型的指针组成.

相反,Go Now会自动取消对方法的参数引用,这样,如果方法接收到指针,则Go会在指向该 struct 的指针上调用该方法,如果该方法接收到一个值,则Go会在该 struct 指向的值上调用该方法.在这一点上,我更新此答案的try 可能遗漏了一些重要的语义内容,因此,如果有人想更正或澄清此问题,请随意添加 comments ,指向更全面的答案.这里有一些围棋操场上的例子来说明这个问题:https://play.golang.org/p/JcD0izXZGz.

在某种程度上,指针和值作为函数上定义的方法的参数工作方式的这种更改会影响下面论述的某些领域,但我将不对睡觉进行编辑,除非有人鼓励我更新它,因为在通过值传递与指针传递的语言的一般语义上下文中,它似乎或多或少是正确的.)

至于指针和值之间的区别,这个例子是说明性的,因为指针通常在Go中使用,以允许您改变变量所指向的值(但也有很多原因可以使用指针!尽管对于典型的使用,这通常是一个可靠的假设).因此,如果将ChangeName定义为:

func (e Event) ChangeName(s string) {
    e.Name = s
}

This function would not be very useful if called on the value receiver, as values (not pointers) won't keep changes that are made to them if they're passed into a function. This has to do with an area of language design around how variables are assigned and passed: What's the difference between passing by reference vs. passing by value?

您可以在这个示例中的Go Playround:https://play.golang.org/p/j7yxvu3Fe6中看到这一点

Go相关问答推荐

迭代项列表时如何超时并发调用

为什么在GO中打印变量会导致堆栈溢出?

golang 的通用 map 功能

困扰围棋官方巡回赛的S建议所有方法都使用同一类型的接收器

ChromeDriver不存在(高朗selenium)

如何使用Gio设置标题栏图标

我找不到pcap.Openlive的设备名称

调用库和直接操作效率有区别吗?

无法在go中为docker容器写入有效的挂载路径

这是实现超时的常见方法,为什么 time.After 不起作用

闭包所处的环境范围是什么?

如何过滤来自 fsnotify 的重复系统消息

如何将一片 map 转换为一片具有不同属性的 struct

如何模仿联合类型

查找、解析和验证邮箱地址

在 Go GRPC 服务器流式拦截器上修改元数据

如何在 golang revel 中获取动态应用程序配置

go 是否对 struct 使用空间填充之类的东西?

Go模板中的浮点除法

为什么在 unsafe.Sizeof() 中取消引用 nil 指针不会导致panic ?