GO面試題-range小坑

語言: CN / TW / HK

1. 題目

type student struct {
	name string
	age  int
}

func main() {
	m := make(map[string]*student)
	stus := []student{
		{name: "小王子", age: 18},
		{name: "娜扎", age: 23},
		{name: "大王八", age: 9000},
	}

	for _, stu := range stus {	  	
		m[stu.name] = &stu
	}
	for k, v := range m {
		fmt.Println(k, "=>", v)
	}
}

2.執行結果

是不是很詫異,結果為什麼不是預期的,map的值都是一個呢?

3.原因分析

for range每次產生的 k , v 都是一個值拷貝,不是 stus對應值得引用,故而會出現這種結果。

stu 是在 for中申請的一個區域性變數, 每次拷貝stus中對應的值。 迭代遍歷之後,stu每次被重新賦值,而map記錄的是 變數stu對應的地址值,故而不會產生預期的效果

4.解決方案

每次重新申請一個變數,即可解決

    for _, stu := range stus {
        aa := stu
        fmt.Printf("%p \n",&aa)   //發現每一個元素的地址都是一樣???              
        m[stu.name] = &aa
    }