藝多不壓身,學習一下最近蠻火的Go語言,整理一下筆記。相關Code和筆記也放到了Git上,傳送門。 數組的聲明var a [3] int //聲明並初始化為預設零值a[0] = 1 b := [3]int{1,2,3} //聲明同時初始化c := [2][2]int{{1,2},{3,4}} //多 ...
藝多不壓身,學習一下最近蠻火的Go語言,整理一下筆記。相關Code和筆記也放到了Git上,傳送門。
數組的聲明
var a [3] int //聲明並初始化為預設零值
a[0] = 1
b := [3]int{1,2,3} //聲明同時初始化
c := [2][2]int{{1,2},{3,4}} //多維數組初始化
Go語言中定義的變數一定要使用,否則會報錯,但如果只是想使用foreach的寫法,可以使用 _ 來占位.
//foreach的寫法, idx即為數組的索引的值
for idx, e:= range arr2 {
t.Log(idx, e)
}
//Go語言中定義的變數一定要使用,所以下麵的寫法會報錯 idx declared but not used
// for idx, e:= range arr2 {
// t.Log(e)
// }
//如果只是想使用foreach的寫法,可以使用 _ 來占位
for _, e:= range arr2 {
t.Log(e)
}
數組截取
a[開始索引(包含), 結束索引(不包含)]
a := [...] int {1,2,3,4,5}
a[1:2] // 2
a[1:3] // 2,3
a[1:len(1)] // 2, 3, 4, 5
a[1:] //2, 3, 4, 5 //從索引1開始一直到末尾
a[:3] //1,2,3 //從索引0開始,一直到索引為3的位置,不包含索引為3的值
---------------------------------------------------------------
切片
切片在別的語言中不一定有,比如c#
使用起來像是可變長數組
切片內部結構
實際上是一個結構體,包含三個元素
1.指針,指向一片連續的存儲空間(一個數組)ptr
2.切片內的元素個數 len
3.指針指向的這個數組的長度,容量 cap
//與聲明數組很類似,區別是沒有指定長度!例如
var s0 []int
利用len()方法來獲得切片內元素個數
利用cap()方法來獲得切片空間大小
利用append(s0, 1)來填充切片
使用make方法來聲明長度和容量不同的切片 例如
//這裡s2長度為3,但容量為5
s2 := make([]int, 3, 5)
其中len個元素會被初始化為預設值0,未初始化元素不可訪問
切片本質上是共用的存儲結構,註意這裡的共用指的是由同一個切片“派生”出的其他切片或數組,例如
year := []string{"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}
q2 := year[3:6]
summer := year[5:8]
year,q2,summer是共用存儲空間的
而反之,如
a := []int{1,2,3,4}
b := []int{1,2,3,4}
雖然初始的值相同,但其實是不共用存儲空間的
---------------------------------------------------------------
數組 VS 切片
1. 容量是否可以伸縮,數組不可以,切片可以
2. 是否可以進行比較,數組可以與數組比較,切片與切片之間不可以比較
附錄:
數組相關Code:
package array_test import "testing" func TestArrayInit(t *testing.T){ var arr [3]int t.Log(arr[1],arr[2]) arr1 := [4]int{1,2,3,4} //不指定長度且初始化時可以用[...] arr2 := [...]int{1,2,3,4,5} arr1[1] = 9 t.Log(arr1[1], arr1[3]) t.Log(arr2[2]) } func TestArrayTraval(t *testing.T){ arr2 := [...]int{1,2,3,4,5} for i:= 0; i < len(arr2); i++{ t.Log(arr2[i]) } //foreach的寫法, idx即為數組的索引的值 for idx, e:= range arr2 { t.Log(idx, e) } //Go語言中定義的變數一定要使用,所以下麵的寫法會報錯 idx declared but not used // for idx, e:= range arr2 { // t.Log(e) // } //如果只是想使用foreach的寫法,可以使用 _ 來占位 for _, e:= range arr2 { t.Log(e) } } func TestArraySection(t *testing.T){ arr3 := [...] int{1,2,3,4,5} arr3_sec := arr3[:3] t.Log(arr3_sec) arr3_sec2 := arr3[3:] t.Log(arr3_sec2) }
切片相關code:
package slice_test import "testing" func TestSliceInit(t *testing.T){ //與聲明數組很類似,區別是沒有指定長度! var s0 []int t.Log(len(s0), cap(s0)) s0 = append(s0, 1) t.Log(len(s0), cap(s0)) //初始化 s1 := []int{1,2,3,4} t.Log(len(s1), cap(s1)) //這裡s2長度為3,但容量為5 s2 := make([]int, 3, 5) t.Log(len(s2), cap(s2)) //這裡會報錯,因為後兩個元素會越界 //t.Log(s2[0],s2[1],s2[2],s2[3],s2[4]) t.Log(s2[0],s2[1],s2[2]) s2 = append(s2, 1) t.Log(s2[0],s2[1],s2[2],s2[3]) } func TestSliceGrowing(t *testing.T){ s:=[]int{} for i:=0; i<10; i++{ s = append(s, i) t.Log(len(s), cap(s)) } //輸出結果 /* TestSliceGrowing: slice_test.go:30: 1 1 TestSliceGrowing: slice_test.go:30: 2 2 TestSliceGrowing: slice_test.go:30: 3 4 TestSliceGrowing: slice_test.go:30: 4 4 TestSliceGrowing: slice_test.go:30: 5 8 TestSliceGrowing: slice_test.go:30: 6 8 TestSliceGrowing: slice_test.go:30: 7 8 TestSliceGrowing: slice_test.go:30: 8 8 TestSliceGrowing: slice_test.go:30: 9 16 TestSliceGrowing: slice_test.go:30: 10 16 */ //每次不夠放的適合,都會將上次的擴展為之前的兩倍,因此要使用類似於s2 = append(s2, 1) 因為是新的空間給s2,並將原來的數據拷貝過去。 } func TestSliceShareMemory(t *testing.T) { year := []string{"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"} q2 := year[3:6] t.Log(q2, len(q2), cap(q2)) //輸出結果為 //TestSliceShareMemory: slice_test.go:53: [Apr May Jun] 3 9,容量是直接到末尾的,所以是9. summer := year[5:8] t.Log(summer, len(summer), cap(summer)) summer[0] = "Unkonw" t.Log(summer, len(summer), cap(summer)) t.Log(q2, len(q2), cap(q2)) //輸出結果為 /* TestSliceShareMemory: slice_test.go:60: [Unkonw Jul Aug] 3 7 TestSliceShareMemory: slice_test.go:61: [Apr May Unkonw] 3 9 */ //由於是共用的存儲空間,因此summer的改動同時影響到了q2的值. } func TestSliceComparing(t *testing.T){ a := []int{1,2,3,4} b := []int{1,2,3,4} //會報錯,nvalid operation: a == b (slice can only be compared to nil) // if(a == b){ // t.Log("Can Compare") // } t.Log(a[2]) t.Log(b[2]) b[2] = 9 t.Log(a[2]) t.Log(b[2]) }