为什么尝试将struct成员作为函数返回类型访问时编译错误?

问题描述 投票:1回答:2

[在golang中,如果我在函数中返回结构类型,则会出现编译错误,我必须使用struct的指针作为返回类型,才能直接通过函数调用实现成员访问。这是为什么? 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
}
go struct field assign
2个回答
1
投票

在Go中,variable是可寻址的值,即可以获取其地址的值。您只能分配给变量,不能分配给不可寻址的值。

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

  1. [bar().Salary实际上是(*bar()).Salary的语法糖;
  2. *bar()是(结构)变量,因为您可以获得其地址;
  3. 结构变量的字段(例如Salary)本身就是变量。

相反,foo().Salary = 1是非法的,因为foo().Salary是一个值,但它是not一个变量;无法获取foo()的地址。这就解释了为什么该语句被编译器拒绝。请注意,引入中间变量可以解决您的问题:

// type and function declarations omitted

func main() {
    f := foo()
    f.Salary = 1 // compiles fine
}

1
投票

foo()返回结构类型的'值',我们不能为该值分配任何内容。而bar()返回指向变量的指针。我们可以使用该指针为该变量分配一个不同的值

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


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的地址。我们可以使用该地址为其分配值

© www.soinside.com 2019 - 2024. All rights reserved.