2 回答

TA貢獻1821條經驗 獲得超5個贊
在調用函數以將其替換為地圖的新版本之前,您將地圖的舊值作為參數傳遞。
假設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 關注
- 134 瀏覽
添加回答
舉報