為什么Go語言中使用for range循環遍歷切片時,map中所有值指向同一內存地址?

為什么Go語言中使用for range循環遍歷切片時,map中所有值指向同一內存地址?

go語言for…range循環map的陷阱

本文分析一個常見的Go語言編程問題,該問題涉及到結構體切片和map的用法,并解釋了為什么使用for…range循環遍歷切片時,map中所有值會指向同一內存地址。理解這個問題對于掌握Go語言的內存管理和引用類型至關重要。

問題描述:

以下代碼片段演示了該問題:

立即學習go語言免費學習筆記(深入)”;

type student struct {     name string     age  int }  func main() {     m := make(map[string]*student)     stus := []student{         {name: "pprof.cn", age: 18},         {name: "測試", age: 23},         {name: "博客", age: 28},     }      for _, stu := range stus {         m[stu.name] = &stu     }     for k, v := range m {         fmt.Println(k, "=>", v.name)     } }

運行結果顯示所有v.name的值都為”博客”。這是因為for…range循環在遍歷切片時,stu變量是一個循環內部的臨時變量,其內存地址在每次迭代中都指向同一個內存位置。 因此,m[stu.name] = &stu 實際上將map中的所有值都指向了同一個student結構體的內存地址,而這個地址在循環結束后指向的是最后一個元素”博客”。

解決方案:

為了避免這個問題,應該在循環中使用切片的索引來獲取元素的地址,如下所示:

for i := range stus {     m[stus[i].name] = &stus[i] }

這種方法確保每個student結構體的地址都是獨立的,從而避免了所有值指向同一內存地址的問題。

總結:

此問題揭示了Go語言for…range循環的特性以及引用類型的行為。理解for…range循環中臨時變量的生命周期,以及如何正確地處理引用類型,對于編寫高效且無錯誤的Go代碼至關重要。 正確使用索引訪問切片元素,可以避免此類內存管理陷阱。

以上就是

? 版權聲明
THE END
喜歡就支持一下吧
點贊6 分享