Golang | 将指针分配给指针接收器不起作用

huangapple go评论85阅读模式
英文:

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.

https://play.golang.org/p/um3JLjzSPrD

huangapple
  • 本文由 发表于 2021年8月2日 23:19:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/68624110.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定