藝多不壓身,學習一下最近蠻火的Go語言,整理一下筆記。相關Code和筆記也放到了Git上,傳送門。git
MAPgithub
Map 聲明golang
m := map[string]int{"one":1, "two":2, "three":3} m1 := map[string]int{} m1["one"] = 1 m2 := make(map[string]int, 10/*Initial Capacity*/) //爲何不初始化len? 對於切片 s := make([]int, 3, 5) 會指定len並給默認的0值,但語義上Map其實沒辦法指定默認值的,所以沒有len.
Map元素的訪問
與其餘主要變成語言的差別
當訪問的Key不存在時,仍會返回零值,不能經過返回nil來判斷元素是否存在,能夠用以下方式判斷數組
if v,ok:=m1[3];ok{ t.Logf("Key 3's value is %d", v) } else { t.Log("Key 3 is not existing.") }
其中ok爲bool值,當值存在時,ok的值爲true函數
Map遍歷學習
m := map[string]int{"one":1, "two":2, "three":3} for k,v := range m { t.Log(k,v) }
附上測試代碼:測試
package my_map import "testing" func TestInitMap(t *testing.T){ m1:=map[int]int{1:1,2:4,3:9} t.Log(m1[2]) t.Logf("len m1=%d", len(m1)) m2:=map[int]int{} m2[4]=16 t.Logf("len m2=%d", len(m2)) m3:=make(map[int]int,10) t.Logf("len m3=%d", len(m3)) //cap()是不能用於求map的capacity的. 下面的code會報錯:invalid argument m3 (type map[int]int) for capgo //t.Logf("len m3=%d", cap(m3)) } func TestAccessNotExistingKey(t *testing.T){ m1:=map[int]int{} t.Log(m1[1]) m1[2] = 0 t.Log(m1[2]) //以上的輸出結果爲 /* TestAccessNotExistingKey: map_test.go:21: 0 TestAccessNotExistingKey: map_test.go:23: 0 */ // 但實際上m1[1]是不存在的值,m1[2]是存在但值爲0,這是兩種狀況 事實上當value不存在時Go會給賦一個默認值 //好處是這樣不會有空指針異常,壞處是須要額外判斷一下是不存在仍是自己就是零值。具體判斷方式以下: if v,ok:=m1[3];ok{ t.Logf("Key 3's value is %d", v) } else { t.Log("Key 3 is not existing.") } m1[3] = 0 if v,ok:=m1[3];ok{ t.Logf("Key 3's value is %d", v) } else { t.Log("Key 3 is not existing.") } } func TestTraveMap(t *testing.T){ m1:=map[int]int{1:1,2:4,3:9} for key,value := range m1{ t.Log(key,value) } }
Map與工廠模式
Map的value能夠是一個方法
與Go的Dock type接口方式一塊兒,能夠方便的實現單一方法對象的工廠模式編碼
實現Set
Go的內置集合中沒有Set實現,能夠map[type]boolspa
添加元素指針
判斷元素是否存在
刪除元素
元素個數
附上代碼:
package map_ext import "testing" func TestMapWithFunValue(t *testing.T){ m:=map[int]func(op int)int{} m[1] =func(op int) int {return op} m[2] =func(op int) int {return op * op} m[3] =func(op int) int {return op * op * op} t.Log(m[1](2),m[2](2),m[3](2)) } func TestMapForSet(t *testing.T){ mySet:=map[int]bool{} //1) 添加元素 mySet[1] = true n:=1 //2) 判斷元素是否存在 if mySet[n] { t.Logf("%d is existing", n) } else { t.Logf("%d is not existing", n) } //3) 刪除元素相似 delete(mySet, 1) //4) 元素個數 t.Log(len(mySet)) // 刪除元素後顯示 1 is not existing if mySet[n] { t.Logf("%d is existing", n) } else { t.Logf("%d is not existing", n) } }
字符串
字符串
與其餘主要變成語言的差別
Unicode 和 UTF8
編碼與存儲
字符 「中」
Unicode 0x4E2D
UTF-8 0XE4B8AD
string/[]byte [0xE4,0xB8,0xAD]
經常使用字符串函數
附上代碼:
package string_test import "testing" func TestString(t *testing.T){ var s string t.Log(s) t.Log(len(s)) s = "\xE4\xB8\xA4" //即便是不可顯示的字符也能夠存儲,如"\xE4\xBB\xA5"將顯示亂 t.Log(s) t.Log(len(s)) //輸出結果爲3,但其實對應的是一箇中文字符 ‘兩’ // string是不能夠變的byte slice,所以不能給它賦值 a := "Hello" //a[1] = '3' // 報錯:cannot assign to a[1]go t.Log(a) b := "中" t.Log(len(b)) //是byte數 c := []rune(b) //rune可以取出字符串中的unicode,這是Go的一個內置機制 t.Log(len(c)) t.Logf("中 unicode %x", c[0]) t.Logf("中 UTF8 %x", s) //以上四個log輸出的結果分別爲: /* TestString: string_test.go:21: 3 TestString: string_test.go:23: 1 TestString: string_test.go:24: 中 unicode 4e2d TestString: string_test.go:25: 中 UTF8 e4b8a4 */ } func TestStringToRune(t *testing.T){ s:= "中華人民共和國" for _,c:=range s{ t.Logf("%[1]c %[1]d",c) } /*d 以上運行結果爲 TestStringToRune: string_test.go:38: 中 20013 TestStringToRune: string_test.go:38: 華 21326 TestStringToRune: string_test.go:38: 人 20154 TestStringToRune: string_test.go:38: 民 27665 TestStringToRune: string_test.go:38: 共 20849 TestStringToRune: string_test.go:38: 和 21644 TestStringToRune: string_test.go:38: 國 22269 注意這裏看代碼可能有些彆扭,這裏的‘%[1]c %[1]d’ 其實意思是 以%c的格式格式化第1個字符 和 以%d的格式格式化第1個字符 */ }