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

我的函数返回一个结构;为什么编译器不允许分配给该结果值的字段?

我的函数返回一个结构;为什么编译器不允许分配给该结果值的字段?

Go
呼唤远方 2022-05-05 17:42:42
在golang中,如果我在函数中返回一个struct类型,会出现编译错误,我必须使用struct的指针作为返回类型,才能通过函数调用直接实现成员访问。这是为什么?foo() 不返回 Employee 类型的临时变量吗?package maintype Employee struct {ID intName stringAddress stringPosition stringSalary intManagerID int}var dilbert Employeefunc foo() Employee {    employee := Employee{}    return employee}func bar() *Employee {    employee := Employee{}    return &employee}func main() {    dilbert.Salary = 1    var b = foo()    b.Salary = 1    bar().Salary = 1    // this is good    foo().Salary = 1    // this line has the compilation error cannot assign to foo().Salary}
查看完整描述

3 回答

?
森林海

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

在 Go 中,变量是可寻址的,即您可以获得地址的值。如果左侧是可寻址的,则分配是有效的。

bar().Salary = 1是合法的,因为

  1. bar().Salary实际上是(*bar()).Salary;的语法糖

  2. *bar()是可寻址的,因为它是指针间接;

  3. 可寻址结构的字段(例如Salary)本身是可寻址的

相比之下,foo().Salary = 1是非法的,因为foo()返回一个值,但它不是变量也不是指针间接;没有办法获得foo()的地址。这就解释了为什么该语句被编译器拒绝。请注意,引入中间变量可以解决您的问题:

// type and function declarations omitted


func main() {

    f := foo()

    f.Salary = 1 // compiles fine

}


查看完整回答
反对 回复 2022-05-05
?
慕运维8079593

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

bar().Salary = 1

返回一个指针,我们正在写入指针指向的对象

foo().Salary = 1

foo() 返回一个临时对象,由于我们没有将它存储在任何地方,如果没有分配给变量,临时对象将会丢失。因此,编译器抱怨

以下将起作用

f = foo()
f.Salary = 1


查看完整回答
反对 回复 2022-05-05
?
狐的传说

TA贡献1804条经验 获得超3个赞

foo() 返回一个结构类型的“值”,我们不能为一个值分配任何东西。而 bar() 返回一个指向变量的指针。我们可以使用这个指针给这个变量分配一个不同的值


此错误本质上与结构无关,而是与将值分配给值有关。考虑以下示例:



func retint() int{

    var a int=5

    return a

}


func retintp() *int{

    var a int=5

    return &a

}

func main(){

    print("hello")

    *retintp()=10   // this is valid as we can store 10 to address pointed by a

    retint()=10     // this gives error. as we can not assign 10 to 5


}

这里 retint() 返回一个值 (5)。我们不能给 5 赋值,但是 retintp() 返回变量 a 的地址。我们可以使用这个地址给它赋值


查看完整回答
反对 回复 2022-05-05
  • 3 回答
  • 0 关注
  • 264 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号