为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
函数式编程 2021-11-22 18:34:33
在 Go 编程语言的第 4.4 节(结构)中,有一段代码摘录:var dilbert Employeefunc EmployeeByID(id int) *Employee { /* ... */ }id := dilbert.IDEmployeeByID(id).salary = 0与此评论如果将 的结果类型EmployeeByID更改为Employee而不是*Employee,则赋值语句将无法编译,因为其左侧无法识别变量。我不明白为什么更改EmployeeByIDto的结果类型Employee会导致 LHS 无法识别变量。
查看完整描述

3 回答

?
森栏

TA贡献1810条经验 获得超5个赞

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


e1 := EmployeeByID(id)

e1.Salary = 0


查看完整回答
反对 回复 2021-11-22
?
慕斯王

TA贡献1864条经验 获得超2个赞

这个简化的例子演示了这个问题:


package main


type t struct {

    int

}


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

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


func main() {

    newT().int = 0

}

我的猜测是,如果您使用newT不返回指针的版本,并且永远不会保存对 的结果的引用newT(),那么设置其int字段的值将永远无法做任何有意义的事情。这类似于设置一个未使用的变量。


如果你使用的是非指针版本newT但你有类似的东西:


x := newT()

x.int = 0

那你就好了。


或者,使用newT上面的指针版本也可以,因为它可能会返回您之前已经定义的某些状态,请参见示例:


package main


type t struct {

    int

}


var dilbert = &t{3}


func newT() *t { return dilbert }


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


func main() {

    println(dilbert.int)

    newT().int = 0

    println(dilbert.int)

}


查看完整回答
反对 回复 2021-11-22
?
慕无忌1623718

TA贡献1744条经验 获得超4个赞

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

这将返回一个指向 Employee 变量的指针。

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

这会返回一个从一个Employee变量复制。在使用它之前,您需要将它分配给一个变量。


查看完整回答
反对 回复 2021-11-22
  • 3 回答
  • 0 关注
  • 126 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信