藝多不壓身,學習一下最近蠻火的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])
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/5029.html
標籤:Go
