[在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中,variable是可寻址的值,即可以获取其地址的值。您只能分配给变量,不能分配给不可寻址的值。
bar().Salary = 1
是合法的,因为
bar().Salary
实际上是(*bar()).Salary
的语法糖;*bar()
是(结构)变量,因为您可以获得其地址;Salary
)本身就是变量。相反,foo().Salary = 1
是非法的,因为foo().Salary
是一个值,但它是not一个变量;无法获取foo()
的地址。这就解释了为什么该语句被编译器拒绝。请注意,引入中间变量可以解决您的问题:
// type and function declarations omitted
func main() {
f := foo()
f.Salary = 1 // compiles fine
}
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的地址。我们可以使用该地址为其分配值