登录
首页 >  Golang >  Go问答

为什么编译器不允许对函数返回的结构体字段进行赋值操作?

来源:stackoverflow

时间:2024-02-24 15:45:26 213浏览 收藏

学习Golang要努力,但是不要急!今天的这篇文章《为什么编译器不允许对函数返回的结构体字段进行赋值操作?》将会介绍到等等知识点,如果你想深入学习Golang,可以关注我!我会持续更新相关文章的,希望对大家都能有所帮助!

问题内容

在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
}

解决方案


在go中,variable是可寻址的,即可以获取地址的值。如果左侧可寻址,则赋值有效。

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
}

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 的地址。我们可以使用这个地址来给它赋值

到这里,我们也就讲完了《为什么编译器不允许对函数返回的结构体字段进行赋值操作?》的内容了。个人认为,基础知识的学习和巩固,是为了更好的将其运用到项目中,欢迎关注golang学习网公众号,带你了解更多关于的知识点!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>