Go語言中的循環與指針問題:為什么v.name都是“博客”?

Go語言中的循環與指針問題:為什么v.name都是“博客”?

go語言循環指針陷阱:詳解v.name全為“博客”的原因

Go語言中的for…range循環和指針結合使用時,容易出現一些令人困惑的問題。本文通過一個例子,深入剖析for…range循環的機制以及指針的使用,解釋為什么代碼輸出結果全為“博客”。

以下代碼片段展示了這個問題:

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)     } }

運行這段代碼,輸出結果將全部是博客。這是因為for…range循環中的stu變量并非每次迭代都創建一個新的變量。它是一個循環變量,其內存地址在整個循環過程中保持不變。 因此,&stu始終指向同一個內存地址。每次迭代都將這個相同的地址賦值給map中的值,最終map中所有指針都指向了最后一個stu變量,即{name: “博客”, age: 28}。

解決方法:創建新的變量副本

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

為了避免這個問題,需要在每次迭代中創建stu的副本,而不是直接使用其地址:

for _, stu := range stus {     s := stu // 創建stu的副本     m[stu.name] = &s }

通過創建新的變量s,m[stu.name] = &s 現在指向的是s的內存地址,而s在每次迭代中都是一個新的變量,從而解決了指針指向同一內存地址的問題,最終輸出結果將正確反映每個學生的姓名。

理解for…range循環的機制以及指針的特性,對于編寫高效且正確的Go代碼至關重要。 避免此類陷阱的關鍵在于,在循環中使用指針時,要確保每個指針都指向不同的內存地址。

以上就是Go語言中的循環與指針問題:

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