我的函数返回一个结构体;为什么编译器不允许对该结果值的字段进行赋值?

Pei*_* Li 3 struct field function go assign

在golang中,如果我在函数中返回结构体类型,则会出现编译错误,我必须使用结构体的指针作为返回类型来直接通过函数调用来实现成员访问。这是为什么?foo() 不是返回一个 Employee 类型的临时变量吗?

package main


type Employee struct {
ID int
Name string
Address string
Position string
Salary int
ManagerID int
}
var dilbert Employee


func 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
}
Run Code Online (Sandbox Code Playgroud)

jub*_*0bs 6

在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
}
Run Code Online (Sandbox Code Playgroud)