在 Go 語言中,map
是一種內建的資料結構,用於儲存鍵值對。map
提供了高效的鍵值對查詢、插入和刪除操作。下面是詳細介紹 map
的使用方法及注意事項。
1. 建立和初始化 map
使用 make
函式建立
可以使用 make
函式建立一個指定型別的 map
。
package main import "fmt" func main() { // 建立一個 key 為 string, value 為 int 的 map myMap := make(map[string]int) fmt.Println(myMap) // 輸出:map[] }
使用字面量初始化
可以直接使用字面量初始化一個 map
,同時設定初始值。
package main import "fmt" func main() { myMap := map[string]int{ "one": 1, "two": 2, "three": 3, } fmt.Println(myMap) // 輸出:map[one:1 two:2 three:3] }
在 Go 語言中,
map
是無序的。每次遍歷或列印map
中的鍵值對時,它們的順序可能不同。這個特性是由 Go 語言的內部實現決定的。即使你使用相同的程式碼,多次執行也可能得到不同的鍵值對順序。具體原因如下:
內部雜湊實現:
map
的鍵是透過雜湊演算法計算得到的,而雜湊演算法的結果在記憶體佈局中並不保證順序。最佳化效能:Go 語言的
map
實現為了最佳化效能和記憶體使用,沒有對鍵值對進行排序。因此,每次遍歷或列印時的順序可能不同。
2. 操作 map
新增和更新元素
使用 map[key] = value
的語法新增或更新 map
中的元素。
package main import "fmt" func main() { myMap := make(map[string]int) myMap["one"] = 1 myMap["two"] = 2 fmt.Println(myMap) // 輸出:map[one:1 two:2] // 更新元素 myMap["one"] = 10 fmt.Println(myMap) // 輸出:map[one:10 two:2] }
訪問元素
使用 map[key]
的語法訪問 map
中的元素。可以使用兩個返回值的方式來判斷鍵是否存在。
package main import "fmt" func main() { myMap := map[string]int{"one": 1, "two": 2} value := myMap["one"] fmt.Println("Value for 'one':", value) // 輸出:Value for 'one': 1 // 判斷鍵是否存在 value, ok := myMap["three"] if ok { fmt.Println("Value for 'three':", value) } else { fmt.Println("'three' does not exist") // 輸出: 'three' does not exist } }
刪除元素
使用 delete
函式從 map
中刪除元素。
package main import "fmt" func main() { myMap := map[string]int{"one": 1, "two": 2} delete(myMap, "one") fmt.Println(myMap) // 輸出:map[two:2] }
3. 遍歷 map
使用 for range
語法遍歷 map
中的所有鍵值對。
package main import "fmt" func main() { myMap := map[string]int{"one": 1, "two": 2, "three": 3} for key, value := range myMap { fmt.Printf("Key: %s, Value: %d\n", key, value) } }
4. 注意事項
map
是無序的
map
中的鍵值對是無序的,每次遍歷的順序可能不同。
零值
map
的零值是 nil
,一個 nil
的 map
不能用於儲存鍵值對,否則會引發執行時錯誤。
package main import "fmt" func main() { var myMap map[string]int fmt.Println(myMap == nil) // 輸出:true // 下面的操作會引發執行時錯誤:panic: assignment to entry in nil map // myMap["one"] = 1 }
併發訪問
map
不是併發安全的。如果需要在多個 goroutine 中併發讀寫同一個 map
,需要使用同步機制(如 sync.Mutex
或 sync.RWMutex
)來確保安全。
package main import ( "fmt" "sync" ) func main() { var wg sync.WaitGroup myMap := make(map[string]int) var mu sync.Mutex for i := 0; i < 5; i++ { wg.Add(1) go func(i int) { defer wg.Done() mu.Lock() myMap[fmt.Sprintf("key%d", i)] = i mu.Unlock() }(i) } wg.Wait() fmt.Println(myMap) }
示例程式碼
下面是一個綜合使用 map
的示例程式碼:
package main import "fmt" func main() { // 建立並初始化 map myMap := map[string]int{"one": 1, "two": 2, "three": 3} // 新增和更新元素 myMap["four"] = 4 myMap["one"] = 10 // 訪問元素 value, ok := myMap["two"] if ok { fmt.Println("Value for 'two':", value) } // 刪除元素 delete(myMap, "three") // 遍歷 map for key, value := range myMap { fmt.Printf("Key: %s, Value: %d\n", key, value) } }