英文:
struct field assignment difference of pointer/non-pointer type
问题
在《The Go Programming Language》的第4.4节(结构体)中,有一段代码摘录:
var dilbert Employee
func EmployeeByID(id int) *Employee { /* ... */ }
id := dilbert.ID
EmployeeByID(id).salary = 0
并附有以下备注:
如果将
EmployeeByID
的结果类型从*Employee
更改为Employee
,那么赋值语句将无法编译,因为其左侧不会识别为变量。
我不明白为什么将EmployeeByID
的结果类型更改为Employee
会导致左侧不识别为变量。
英文:
In section 4.4 (Structs) of The Go Programming Language, there is a code excerpt:
var dilbert Employee
func EmployeeByID(id int) *Employee { /* ... */ }
id := dilbert.ID
EmployeeByID(id).salary = 0
with the remark
> If the result type of EmployeeByID
were changed to Employee
instead of *Employee
, the assignment statement would not compile since its left-hand side would not identify a variable.
I don't understand why changing the result type of EmployeeByID
to Employee
would cause LHS not identify a variable.
答案1
得分: 2
这个简化的示例演示了问题:
package main
type t struct {
int
}
func newT() *t { return &t{} }
//func newT() t { return t{} }
func main() {
newT().int = 0
}
我猜测,如果你使用不返回指针的newT
版本,并且从不保存newT()
结果的引用,那么设置其int
字段的值就没有任何意义。这类似于设置一个未使用的变量。
如果你使用非指针版本的newT
,但是有类似以下的代码:
x := newT()
x.int = 0
那么就没问题。
另外,使用上面的指针版本的newT
也是可以的,因为它可能返回你之前已经定义的某些状态,参见示例:
package main
type t struct {
int
}
var dilbert = &t{3}
func newT() *t { return dilbert }
//func newT() t { return t{} }
func main() {
println(dilbert.int)
newT().int = 0
println(dilbert.int)
}
英文:
This simplified example demonstrates the issue:
package main
type t struct {
int
}
func newT() *t { return &t{} }
//func newT() t { return t{} }
func main() {
newT().int = 0
}
My guess is that if you use the version of newT
that does not return a pointer, and never save off a reference to the result of newT()
, then setting the value of its int
field can never meaningfully do anything. It's similar to setting an unused variable.
If instead you the non-pointer version of newT
but you have something like:
x := newT()
x.int = 0
Then you'd be fine.
Alternatively, using the pointer version of newT
above is fine, because it could be returning some state you already had defined previously, see example:
package main
type t struct {
int
}
var dilbert = &t{3}
func newT() *t { return dilbert }
//func newT() t { return t{} }
func main() {
println(dilbert.int)
newT().int = 0
println(dilbert.int)
}
答案2
得分: 2
我已经研究了这个问题,我认为如果你将*Employee更改为Employee,那么EmployeeByID(id)将成为一个不可寻址的值,因为它没有被分配给一个变量。如果你像下面这样给它分配一个变量,那就没问题了:
e1 := EmployeeByID(id)
e1.Salary = 0
英文:
I have researched on this topic, and I think the problem if you change to Employee instead of *Employee, then EmployeeByID(id) will be a unaddressable value since it is not assigned to a variable. It is OK if you assign it a variable like below:
e1 := EmployeeByID(id)
e1.Salary = 0
答案3
得分: 1
func EmployeeByID(id int) Employee { / ... */ }
这个函数返回一个指向Employee变量的指针。
func EmployeeByID(id int) Employee { /* ... */ }
这个函数返回从Employee变量复制的值。在使用之前,你需要将其赋值给一个变量。
英文:
func EmployeeByID(id int) *Employee { /* ... */ }
This return a pointer to an Employee variable.
func EmployeeByID(id int) Employee { /* ... */ }
This returns a value copied from an Employee variable. You need to assign it to a variable before using it.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论