2 回答

TA貢獻(xiàn)1821條經(jīng)驗(yàn) 獲得超5個(gè)贊
在調(diào)用函數(shù)以將其替換為地圖的新版本之前,您將地圖的舊值作為參數(shù)傳遞。
假設(shè)packageA.M包含值map[string]string{"foo": "bar"}。該main()函數(shù)讀取變量并獲取對(duì)該映射的引用,并將它和函數(shù)傳遞給packageB.UseMap().
在 內(nèi)部packageB.UseMap(),您的代碼packageA.InitMap()通過(guò)回調(diào)進(jìn)行調(diào)用。這不會(huì)修改現(xiàn)有地圖;相反,它會(huì)創(chuàng)建一個(gè)新地圖,將其分配給全局變量并填充它。任何擁有舊地圖副本的東西都不會(huì)受到影響,并且您顯示的代碼不會(huì)重新讀取packageA.M.
我建議完全放棄全局變量:它會(huì)使代碼難以測(cè)試,并且一旦開(kāi)始使用 goroutines 就會(huì)出現(xiàn)潛在問(wèn)題。只需讓您的設(shè)置函數(shù)返回新地圖即可。
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貢獻(xiàn)1846條經(jīng)驗(yàn) 獲得超7個(gè)贊
就像已接受的答案的旁注一樣,如果您看一下:
// ...
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 關(guān)注
- 141 瀏覽
添加回答
舉報(bào)