2 回答

TA贡献1821条经验 获得超4个赞
在调用函数以将其替换为地图的新版本之前,您将地图的旧值作为参数传递。
假设packageA.M包含值map[string]string{"foo": "bar"}。该main()函数读取变量并获取对该映射的引用,并将它和函数传递给packageB.UseMap().
在 内部packageB.UseMap(),您的代码packageA.InitMap()通过回调进行调用。这不会修改现有地图;相反,它会创建一个新地图,将其分配给全局变量并填充它。任何拥有旧地图副本的东西都不会受到影响,并且您显示的代码不会重新读取packageA.M.
我建议完全放弃全局变量:它会使代码难以测试,并且一旦开始使用 goroutines 就会出现潜在问题。只需让您的设置函数返回新地图即可。
package packageA
func InitMap() map[string]string {
return map[string]string{"hello": "go"}
}
package packageB
func UseMap(callback func() map[string]string) {
m := callback()
fmt.Println(m)
}
package main
import "packageA"
import "packageB"
func main() {
packageB.UseMap(packageA.InitMap)
}

TA贡献1846条经验 获得超7个赞
就像已接受的答案的旁注一样,如果您看一下:
// ...
import (
"reflect"
"fmt"
)
// ... other functions
// I defined all of the functions in a single paackage, so I can access them both here
func UseMap(m map[string]string, callback func()) {
fmt.Println(reflect.ValueOf(m).Pointer() == reflect.ValueOf(M).Pointer()) // prints true, they have the same reference
callback()
// inside callback, M global variable takes a whole new reference
// when "M = make(...)"
// and then =>
fmt.Println(reflect.ValueOf(m).Pointer() == reflect.ValueOf(M).Pointer()) // prints false
}
如果你想在不改变你的 api 的情况下避免这种情况,你可以在你的包 A 中这样做:
package packageA
var M map[string]string = make(map[string]string)
func InitMap() {
M["hello"] = "go"
}
- 2 回答
- 0 关注
- 114 浏览
添加回答
举报