[Golang] maps
在 Go 中,Map 也是 Key-Value pair 的組合,但是 Map 所有 Key 的資料型別都要一樣;所有 Value 的資料型別也要一樣。另外,在設值和取值需要使用 []
而非 .
。map 的 zero value 是 nil
。
The anatomy of maps in Go @ run go
建立 Map 的方式
// m := map[Tkey]Tvalue{}
func main() {
// 第一種方式
// 建立一個型別為 map 的變數,其中的 key 都會是 string,value 也都會是 string
colors := map[string]string{}
// 也可以直接帶值
colors := map[string]string{
"red": "#ff0000",
"green": "#4bf745",
}
// 第二種方式
var colors map[string]string
// 第三種方式,使用 make 建立 Map。
// Key 的型別是 string,Value 是 int
colors := make(map[string]int)
colors["red"] = 10
fmt.Println(colors) // map[red:10]
// 如果對於鍵值的數量有概念的話,也可以給定初始大小,將有助於效能提升(The little Go book)
m := make(map[string]int, 100)
}
Map 的 value 是 struct
// Map 的 value 是 struct
type Vertex struct {
Lat, Long float64
}
func main() {
// 使用 make 建立 Map
m := make(map[string]Vertex)
m["Bell Labs"] = Vertex{
40.68443, -74.39967,
}
// 使用 Map Literal 建立 Map
mapLiteral := map[string]Vertex{
"Bell Labs": Vertex{
40.68433, -74.39967,
},
"Google": Vertex{
37.42202, -122.08408,
},
}
// Struct Type 的名稱可以省略
mapLiteral := map[string]Vertex{
"Bell Labs": {
40.68433, -74.39967,
},
"Google": {
37.42202, -122.08408,
},
}
}
Map 的操作
keywords: delete
, len
在 map 中因為 key 本身是有資料型別的,因此只能使用 []
來設值和取值,不能使用 .
:
- 使用
len()
可以取得 map 鍵值的數量 - 使用
delete(map, key)
可以移除 map 中的鍵值 - 使用
value, isExist := m[key]
可以用來取值,同時判斷該key
是否存在
func main() {
colors := make(map[int]string)
// 先增 map 中的 key-value
colors[10] = "#ffffff"
colors[1] = "#4bf745"
// 使用 len 可以取得 map 鍵值的數量
fmt.Println(len(colors)) // 2
// 移除 map 中的資料,delete(m, key)
delete(colors, 10)
// 取值
fmt.Println(colors[10])
// 檢查某 Map 中是否存在該 key
// value, isExist = m[key]
//
// 該 key 存在的話 isExist 會是 true,否則會是 false
// 該 key 存在的話 value 會回傳該 map 的值,否則回傳該其 zero value
value, isExist := colors[1] // #4bf745 true
value, isExist = colors[10] // "", false
}
Map 的疊代
keywords: range
func main() {
colors := map[string]string{
"red": "#ff0000",
"green": "#4bf745",
"white": "#ffffff",
}
// 疊代 map
printMap(colors)
}
// 因為 map 是 reference type,所以不用使用 pointer
func printMap(c map[string]string) {
for color, hex := range c {
fmt.Printf("%v: %v\n", color, hex)
}
}
Map 和 Structure 的選擇
Map | Structure |
---|---|
所有的 key 都需要是相同型別 | |
所有的 value 都需要是相同型別 | value 可以是不同型別 |
Key 有被 indexed,因此可以進行疊代,列出所有的 key-value pairs | Key 沒有被 indexed,因此沒辦法透過疊代的方式列出所有的 key-value pair |
Reference Type | Value Type |
通常用在資料集合關聯性非常強的資料,例如 colors | 通常用在一個帶有多種屬性的東西,例如 person |
不用一開始就知道所有的 key 有哪些,因為可以後續新增和刪除 | 需要一開始就清楚定義所有的欄位 |