Golang结构初始化

she*_*per 19 go

有一个像这样的简单结构:

type Event struct {
    Id         int
    Name       string
}
Run Code Online (Sandbox Code Playgroud)

这两种初始化方法有什么区别?

e1 := Event{Id: 1, Name: "event 1"}
e2 := &Event{Id: 2, Name: "event 2"}
Run Code Online (Sandbox Code Playgroud)

我为什么要使用这些初始化方法?

谢谢

Cle*_*vas 20

第一种方法

e1 := Event{Id: 1, Name: "event 1"}
Run Code Online (Sandbox Code Playgroud)

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

e2 := &Event{Id: 1, Name: "event1"}
Run Code Online (Sandbox Code Playgroud)

正在初始化e2为指向类型值的指针Event 正如您在注释中所述,在给定类型的值上定义的方法集是在指向该类型值的指针上定义的方法集的子集.这意味着如果你有一个方法

func (e Event) GetName() string {
    return e.Name
}
Run Code Online (Sandbox Code Playgroud)

那么这两个e1e2可以调用此方法,但如果你有其他方法,比如:

func (e *Event) ChangeName(s string) {
    e.Name = s
}
Run Code Online (Sandbox Code Playgroud)

然后e1就是无法使用该ChangeName方法e2.

这(e1无法使用ChangeName方法,同时e2是)事实并非如此(虽然它可能已经在写此帮助时),由于@DannyChen在提出这个问题,并@GilbertNwaiwu用于测试和发布评论如下.

(为了解决上面的罢工部分:在结构类型上定义的方法集包括为类型定义的方法和指向类型的指针.

相反,转到现在自动取消引用参数的方法,所以,如果一个方法接收一个指针,去呼吁一个指针结构的方法,如果方法临危值,围棋呼吁价值指向的方法那个结构.在这一点上,我更新这个答案的尝试可能会遗漏一些重要的语义,所以如果有人想要纠正这个或澄清随意添加一个指向更全面的答案的评论.这里有一些来自go操场说明这个问题:https://play.golang.org/p/JcD0izXZGz.

在某种程度上,指针和值如何作为函数定义的方法的参数的这种变化影响了下面的话语的某些方面,但是我将保留其余的未经编辑的,除非有人鼓励我更新它,因为它似乎或多或少是正确的通过值与指针传递的语言的一般语义的上下文.)

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

func (e Event) ChangeName(s string) {
    e.Name = s
}
Run Code Online (Sandbox Code Playgroud)

如果在值接收器上调用此函数将不会非常有用,因为值(不是指针)将不会保留对它们进行的更改(如果它们被传递到函数中).这与围绕如何分配和传递变量的语言设计领域有关:通过引用传递与传递值之间的区别是什么?

你可以在Go Playground的这个例子中看到这个:https://play.golang.org/p/j7yxvu3Fe6


eva*_*nal 6

的类型e1Event的类型e2*Event。初始化实际上是相同的(使用复合文字语法,也不确定该术语是 Go 还是 C# 还是两者?),但是使用e2“运算符地址” &,因此它返回指向该对象的指针而不是实例本身。