struct字段赋值指针/非指针类型的差异

时间:2015-11-22 03:06:16

标签: go

在Go Go Programming Language的4.4节(Structs)中,有一段代码摘录:

var dilbert Employee
func EmployeeByID(id int) *Employee { /* ... */ }
id := dilbert.ID
EmployeeByID(id).salary = 0

带有评论

  

如果EmployeeByID的结果类型更改为Employee而不是*Employee,则赋值语句将无法编译,因为其左侧不会标识变量。

我不明白为什么将EmployeeByID的结果类型更改为Employee会导致LHS无法识别变量。

3 个答案:

答案 0 :(得分:1)

simplified example演示了此问题:

package main

type t struct {
    int
}

func newT() *t { return &t{} }
//func newT() t { return t{} }

func main() {
    newT().int = 0
}

我的猜测是,如果您使用不返回指针的newT版本,并且永远不会保存对newT()结果的引用,则设置其{{1}的值} field永远不会有意义地做任何事情。它与设置未使用的变量类似。

如果您使用的是int的非指针版本,但您有类似的内容:

newT

然后你没事。

或者,使用上面x := newT() x.int = 0 的指针版本很好,因为它可能会返回您之前已经定义的某个状态,请参阅example

newT

答案 1 :(得分:1)

我已经研究了这个主题,我认为如果你改为Employee而不是* Employee,那么问题就是EmployeeByID(id)将是一个不可追址的值,因为它没有分配给变量。如果你给它分配一个如下变量就可以了:

e1 := EmployeeByID(id)
e1.Salary = 0

答案 2 :(得分:1)

func EmployeeByID(id int) *Employee { /* ... */ }

返回指向Employee变量的指针。

func EmployeeByID(id int) Employee { /* ... */ }

这将返回从Employee变量复制的。在使用之前,您需要将其分配给变量。