英文:
Golang | Assign a pointer to a pointer receiver not working
问题
我不明白为什么当指针接收器被赋予指向另一个对象的指针时,它不会被更新。
这是一个例子:
- Get是一个导出的getter函数,
- get是未导出的函数。
我希望Get()返回一个指向由字符串索引的指针映射中的对象的指针。
我不明白为什么get()方法的指针接收器没有被更新。
我尝试了不同的策略,几乎每次都得到相同的结果:解引用,在变量声明中使用&代替*...
Go Playground链接:https://play.golang.org/p/zCLLvucbMjy
有什么想法吗?谢谢!
package main
import (
"fmt"
)
type MyCollection map[string]*MyType
type MyType struct {
int
}
var collection MyCollection
func Get(key string) *MyType {
var rslt *MyType
// rslt := &MyType{}: gives almost the same result
rslt.get(key)
fmt.Println("rslt:", rslt) // Should print "rslt: &{2}"
return rslt
}
func (m *MyType) get(key string) {
m = collection[key]
// *m = collection[key] : cannot use collection[key] (type *MyType) as type MyType in assignment
fmt.Println("get m:", m) // Should print "get m: &{2}"
}
func main() {
collection = make(map[string]*MyType)
collection["1"] = &MyType{1}
collection["2"] = &MyType{2}
m := &MyType{1}
m = Get("2")
fmt.Println("final m", m) // Should print "final m: &{2}"
}
英文:
I do not understand why a pointer receiver is not updated when being assigned a pointer to another object.
Here is an example:
- Get is an exported getter,
- get is unexported,
I want Get() to return a pointer to an object, contained in a map of pointers indexed by strings.
I do not get why the pointer receiver of the get() method is not updated.
I tried different strategies with almost the same result each time: dereferencing, using & instead of * in variables declarations...
Go playground here: https://play.golang.org/p/zCLLvucbMjy
Any idea ?
Thanks !
package main
import (
"fmt"
)
type MyCollection map[string]*MyType
type MyType struct {
int
}
var collection MyCollection
func Get(key string) *MyType {
var rslt *MyType
// rslt := &MyType{}: gives almost the same result
rslt.get(key)
fmt.Println("rslt:", rslt) // Should print "rslt: &{2}"
return rslt
}
func (m *MyType) get(key string) {
m = collection[key]
// *m = collection[key] : cannot use collection[key] (type *MyType) as type MyType in assignment
fmt.Println("get m:", m) // Should print "get m: &{2}"
}
func main() {
collection = make(map[string]*MyType)
collection["1"] = &MyType{1}
collection["2"] = &MyType{2}
m := &MyType{1}
m = Get("2")
fmt.Println("final m", m) // Should print "final m: &{2}"
}
答案1
得分: 1
你需要对接收器进行解引用,并将其赋值为来自映射的解引用值,即*m = *collection[key]
。
在调用rslt.get
之前,请确保变量rslt
已初始化且不是nil
,例如rslt := &MyType{}
。
func Get(key string) *MyType {
rslt := &MyType{}
rslt.get(key)
fmt.Println("rslt:", rslt) // 应该打印出 "rslt: &{2}"
return rslt
}
func (m *MyType) get(key string) {
*m = *collection[key]
fmt.Println("get m:", m) // 应该打印出 "get m: &{2}"
}
请注意,m = collection[key]
不足够的原因是,接收器始终是调用者变量的副本。直接对接收器赋值只会更新该副本,而不会更改调用者的变量。要更新接收器和调用者变量所指向的数据,您需要对变量进行解引用。请注意,每次调用都会得到自己的副本。
注意,m = collection[key]
不足够的原因是,接收器始终是调用者变量的副本。直接对接收器赋值只会更新该副本,而不会更改调用者的变量。要更新接收器和调用者变量所指向的数据,您需要对变量进行解引用。请注意,每次调用都会得到自己的副本。
链接:https://play.golang.org/p/zhsC9PR3kwc
请注意,m = collection[key]
不足够的原因是,接收器始终是调用者变量的副本。直接对接收器赋值只会更新该副本,而不会更改调用者的变量。要更新接收器和调用者变量所指向的数据,您需要对变量进行解引用。请注意,每次调用都会得到自己的副本。
链接:https://play.golang.org/p/um3JLjzSPrD
英文:
You need to dereference the receiver and assign to it a dereference value from the map, i.e. *m = *collection[key]
.
Make sure that before you call rslt.get
the variable rslt
is initialized and not nil
, e.g. rslt := &MyType{}
.
func Get(key string) *MyType {
rslt := &MyType{}
rslt.get(key)
fmt.Println("rslt:", rslt) // Should print "rslt: &{2}"
return rslt
}
func (m *MyType) get(key string) {
*m = *collection[key]
fmt.Println("get m:", m) // Should print "get m: &{2}"
}
https://play.golang.org/p/zhsC9PR3kwc
Note that the reason m = collection[key]
isn't enough is because the receiver is always a copy of the caller's variable. And assigning to the receiver directly will just update that copy and not change the caller's variable. To update the data to which both, the receiver and the caller's variable, point to, you have to dereference the variable. And note that each call gets its own copy.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论