iT邦幫忙

2021 iThome 鐵人賽

DAY 14
0
Modern Web

還喝不 go系列 第 14

[13th][Day14] map

移除元素
如果要從切片中移除元素,下面是一個比較簡單粗暴的寫法

    slice := []int{1, 2, 3, 4, 5}
 
    // 移除第三個 element
    slice = append(slice[0:2], slice[3:5]...)
 
    if !(len(slice) == 4) {
        log.Fatal("Wrong length")
    }
}

這種寫法的條件是知道要刪 『第幾個 element』 時才能寫
golang 並沒有移除元素的方法,上述只是從中截斷,再重組
可以用 struct 當作 element ,在 slice 中存更多樣的資料

通常在宣告一個空 slice 時 ,該 slice 是沒有 len 的

    x:=[]string{}
	x[0] = "1"

上述寫法會導致 panic

panic: runtime error: index out of range [0] with length 0

請使用 append 方法

	x := []string{}
	x = append(x, "1")

只能 append 同資料型態的變數/struct

golang 的 map 指的並不是地圖
而是一組可以自定義 key 的 key/value 資料組合

google 了半天我還是沒找到一個公認的 map 標準用中文名稱
只查到很多概念類似、或是有人使用的名詞、而且大部分來自對岸QQ

「映射」「哈希」 「集合」 「關連性陣列」 ... etc

make map

建一個 key & value 型態皆為 string 的 map

    m := make(map[string]string)
 
    m["Python"] = "Django"
    m["JavaScript"] = "Angular"
    m["Go"] = "Beego"
    m["PHP"] = "Laravel"


	for k,v:= range m {
        fmt.Println(k,v)
	}
}

check 是否存在這個 key
如果鍵/值對不存在,會依 map 的值 的型別回傳預設值

    m := make(map[string]string)
 
    m["Go"] = "Beego"
    m["Python"] = "Django"
    m["Ruby"] = "Rails"
    m["PHP"] = "Laravel"
 
	fmt.Println(m["Java"])
    if m["Java"]=="" {
		fmt.Println("真的是空的")
	}
}

因為根本沒有 Java 這個 key,所以 m["Java"] 會依原本宣告的 value 格式給預設值
about 預設值

When storage is allocated for a variable, either through a declaration or a call of new, or when a new value is created, either through a composite literal or a call of make, and no explicit initialization is provided, the variable or value is given a default value. Each element of such a variable or value is set to the zero value for its type: false for booleans, 0 for numeric types, "" for strings, and nil for pointers, functions, interfaces, slices, channels, and maps. This initialization is done recursively, so for instance each element of an array of structs will have its fields zeroed if no value is specified.

https://golang.org/ref/spec#The_zero_value

false for booleans
0 for numeric
"" for strings
nil for pointers, functions, interfaces, slices, channels, and maps

如果不確定 key 是否存在,可以用 ok 來做檢查

    m := make(map[string]string)
 
    m["Go"] = "Beego"
    m["Python"] = "Django"
    m["Ruby"] = "Rails"
    m["PHP"] = "Laravel"
 
    v, ok := m["Go"]
    fmt.Println(v, ok)
}

ok 可以自己定義要用什麼字眼,上面的 ok 是一個 bool ,如果 m["Go"] 存在回 true,如果不存在回 false

map vs slice
兩者皆為 go 中重要的變數型態

Slice:
Slice 是 base on array 的一種資料型態。
Slice 主要功能在於其擴充性 以及 append 方法。
Slice 擁有一個指向開始位置的「pointer ptr」、「長度 len」、「最大容量 cap」。
Slice 可以依需求增長或收縮。Slice 的增長通常包括為內存的重新分配。像 copy 和 append 這樣的 func 可以幫助我增加 slice 的長度。

Map:
golang 常用於 web 的後端,那麼在彼此跟彼此之間溝通時常常會用到 json 格式,json 格式跟 map 的相性非常非常的契合
儲存 key 可以為非 int (比方說: string) 的 slice
map 可以自定義 key 則提供了許多不同的使用方式


上一篇
[13th][Day13] slice
下一篇
[13th][Day15] nil
系列文
還喝不 go20

尚未有邦友留言

立即登入留言