Go語言Map迭代陷阱:為何所有值都指向最後一個元素?
Go語言中的for...range
循環與map
數據結構結合使用時,容易出現一個常見的陷阱:當遍歷切片並將元素添加到map
中時,所有map
的值最終都指向最後一個元素。本文將通過代碼示例分析其原因,並提供解決方案。
讓我們來看一段代碼:
type Student struct { Name string Age int } func main() { m := make(map[string]*Student) students := []Student{ {Name: "pprof.cn", Age: 18}, {Name: "測試", Age: 23}, {Name: "博客", Age: 28}, } for _, stu := range students { m[stu.Name] = &stu // 問題出在這裡} for k, v := range m { fmt.Println(k, "=>", v.Name) } }
這段代碼的預期結果是將students
切片中的每個Student
結構體存儲到map
中。然而,運行結果卻顯示所有map
的值都指向最後一個元素“博客”:
<code>pprof.cn => 博客测试=> 博客博客=> 博客</code>
問題根源: for...range
循環的變量作用域
問題在於for...range
循環中, stu
變量並非每次迭代都創建一個新的變量。它指向的是students
切片中同一個內存地址。每次迭代, stu
的值都會被更新,但其內存地址保持不變。因此,當循環結束後, map
中的所有指針都指向stu
的最終值(最後一個元素)。
解決方案:創建新的變量副本
為了解決這個問題,我們需要在每次迭代中創建一個stu
變量的副本,確保map
中存儲的是不同的內存地址。修改後的代碼如下:
for _, stu := range students { newStu := stu // 創建副本m[newStu.Name] = &newStu }
或者,更簡潔的方法是直接創建新的Student
結構體:
for _, stu := range students { m[stu.Name] = &Student{Name: stu.Name, Age: stu.Age} // 創建新的Student實例}
通過以上修改, map
中的每個值將指向不同的內存地址,從而避免了所有值都指向最後一個元素的情況。 運行修改後的代碼將得到預期的結果。
希望這個解釋能夠幫助您理解Go語言中for...range
循環和map
數據結構的細節,並避免此類陷阱。
以上是為什麼Go語言中使用for range遍歷slice並存入map時,所有值會變成最後一個元素?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本文討論了使用GO的“字符串”軟件包進行字符串操作,詳細介紹了共同的功能和最佳實踐,以提高效率並有效地處理Unicode。

本文詳細介紹了GO的“時間”包用於處理日期,時間和時區,包括獲得當前時間,創建特定時間,解析字符串以及測量經過的時間。

文章討論了使用GO的“同步/原子”軟件包進行並行編程中的原子操作,詳細說明了其益處,例如防止比賽條件和提高性能。

本文討論了GO中的類型轉換,包括語法,安全轉換實踐,常見的陷阱和學習資源。它強調明確的類型轉換和錯誤處理。 [159個字符]

本文解釋了在GO中使用“選擇”語句來處理多個頻道操作的使用,其與“開關”語句的差異以及常見用例,例如處理多個渠道,實現超時,非B


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

MantisBT
Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

EditPlus 中文破解版
體積小,語法高亮,不支援程式碼提示功能

SublimeText3 英文版
推薦:為Win版本,支援程式碼提示!

SublimeText3 Linux新版
SublimeText3 Linux最新版

記事本++7.3.1
好用且免費的程式碼編輯器