为什么返回结构体而非结构体指针时无法进行赋值操作?
Go中结构体值与指针返回值的赋值差异解析
先看第一种报错的代码:
type Profile struct { id int name string } func test(p Profile) Profile { return p } func main() { var profile Profile test(profile).id = 20 // cannot assign to test(profile).id (value of type int) }
这段代码里,test函数返回的是Profile类型的值副本。调用test(profile)得到的是一个未绑定到任何变量的临时值,Go语言语法明确禁止对这类临时值的字段直接赋值——因为临时值用完就会被销毁,赋值操作没有实际意义,编译器会直接报错阻止这种无效操作。
再看修改后可正常运行的代码:
type Profile struct { id int name string } func test(p Profile) *Profile { return &p } func main() { var profile Profile test(profile).id = 20 // Works }
这里test返回的是*Profile类型的指针。Go语言中指针是可寻址的,当你用test(profile).id时,.操作符会自动对指针解引用,最终操作的是指针指向的内存地址里的字段值。哪怕指针指向的是函数内部的局部变量(编译器会自动处理局部变量逃逸到堆的情况,避免函数退出后变量被释放),语法上这个操作是合法的,因为你是对一个可寻址的内存位置赋值,所以编译器允许执行。
总结核心差异:
- 返回结构体值时,得到的是临时不可寻址值,无法直接修改其字段
- 返回结构体指针时,得到的是可寻址的指针,通过指针可直接修改指向的结构体字段
内容的提问来源于stack exchange,提问作者XPD
相关产品推荐
相关产品推荐

