跳至主要内容

[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 的選擇

MapStructure
所有的 key 都需要是相同型別
所有的 value 都需要是相同型別value 可以是不同型別
Key 有被 indexed,因此可以進行疊代,列出所有的 key-value pairsKey 沒有被 indexed,因此沒辦法透過疊代的方式列出所有的 key-value pair
Reference TypeValue Type
通常用在資料集合關聯性非常強的資料,例如 colors通常用在一個帶有多種屬性的東西,例如 person
不用一開始就知道所有的 key 有哪些,因為可以後續新增和刪除需要一開始就清楚定義所有的欄位

參考