Go語言基礎之陣列 切片和對映
阿新 • • 發佈:2021-10-31
Go語言基礎之陣列 切片 和對映
陣列
陣列:相同型別的一組資料,一旦定義之後,大小不能發生改變
下面是運算元組的一些栗子
func test( a[5] int) int { //陣列作引數時必須規定大小和型別
return a[0]
}
func main() {
//幾種宣告和初始化陣列的方式
var a [5] int //僅宣告
a[0],a[1],a[2]=3,4,5
fmt.Println(a,len(a),cap(a))
var b =[5] int {1,2,3} //宣告的時候初始化 注意數值個數必須比陣列大小要小
fmt.Println(b,len(b),len(b))
var c=[] int {1,2,3,4} //不規定大小的初始化,Go自動根據個數設定大小
fmt.Println(c,len(c),cap(c))
d:=[] float64{5.0,6.0,7.0}
fmt.Println(d,len(d),cap(d))
e:=[...] int{0:2,5:9,9:11} //在特定位置賦值
fmt.Println(e,len(e),cap(e))
//陣列是值型別,對賦值的新變數進行修改,不會在原始陣列中表現出來
f:=a
f[0]=999
fmt.Println(a,len(a),cap(a))
fmt.Println(f,len(f),cap(f))
//多維陣列
var n =[2][2]int {{1,2},{3,4}}
fmt.Println(n,len(n),cap(n))
//多維陣列的遍歷
for _,v :=range n {
for _,v2:= range v {
fmt.Println(v,v2)
}
}
//陣列作為引數
fmt.Println(test(a),test(b))
}
//
輸出:
[3 4 5 0 0] 5 5
[1 2 3 0 0] 5 5
[1 2 3 4] 4 4
[5 6 7] 3 3
[2 0 0 0 0 9 0 0 0 11] 10 10
[3 4 5 0 0] 5 5
[999 4 5 0 0] 5 5
[[1 2] [3 4]] 2 2
[1 2] 1
[1 2] 2
[3 4] 3
[3 4] 4
3 1
注意:
-
遍歷陣列的兩種方式分別是for i<len(arraryname)和 for range **
-
陣列是值型別
-
陣列作為形參要規定長度
-
陣列支援邏輯運算子== !=等,其中==成立的陣列,每個元素的值都要等
-
[n] * type表示指標陣列,* [n] type 表示陣列指標
-
對陣列使用[:]冒號運算子的時候,其實是通過指標進入到數組裡資料的地址,對其進行拷貝或者修改,也就是說修改擷取之後新的陣列的值,是會改變原陣列的值的
切片
切片:Go的切片是對陣列的抽象,與陣列相比,切片的長度是不固定的。可以追加元素(不僅增加了切片的len也增加了cap),本質是封裝好的陣列,包含了三個資訊:底層陣列的指標,切片的長度和切片的容量
關於切片的一些操作
func main() {
var a [] int
b:=make([]int,10) // 10為length
b[0]=2
c:=make([]int,10,20) //10為length ,20為cap]
d:=[] int {2,3,4,5,6,7,8,9,0,1}
/*a[0]=1
a[1]=2
a[2]=3 */ //當聲明瞭切片 卻沒有給len的時候,再進行賦值是會報錯的
//因為我們聲明瞭卻沒有例項化 那麼len和cap都是0 賦值的過程相當於下標溢位
a=append(a,1) //用append塞進去是對的
//: 運算子
fmt.Println(d[:])
e:=d[1:4]//d[1] 到 d[3] 即 3 4 5
fmt.Println(e,len(e),cap(e))
fmt.Println(len(a),cap(a))
fmt.Println(len(b),cap(b))
fmt.Println(len(c),cap(c)) //len是切片中元素的數量 cap是從建立切片的索引開始的底層陣列中元素的數量
//更改切片的值 因為切片是引用傳遞 所有相關的副本都會反映出來
d[1]=20
fmt.Println(d[:])
fmt.Println(e[:])
copy(c,b) //把b的值拷貝到c中
b[0]=1
fmt.Println(b)
fmt.Println(c) //copy之後改變原來的slice的值,是不會對新slice產生影響的
}
檢查切片是否為空
var s1 []int //len(s1)=0;cap(s1)=0;s1==nil
s2 := []int{} //len(s2)=0;cap(s2)=0;s2!=nil 因為已經初始化陣列了
s3 := make([]int, 0) //len(s3)=0;cap(s3)=0;s3!=nil
//應該用len(s)==0 判斷,而不是s==nil
比較兩個切片
引用型別是不能直接比較的,只能和nil進行比較,值型別是可以直接比較的
刪除切片的方法
要從切片a中刪除索引為index的元素,操作方法是a = append(a[:index], a[index+1:]...) //要把一個切片append到另一個切片裡 一定要寫...
//把一個數或者幾個數往slice裡面append可以直接寫
//把slice往slice裡面塞,字尾一定要用...
切片的複製
我們可以用等號直接將一個切片賦值給另一個切片,但是這不是值傳遞,而是引用傳遞,即一個切片的值被修改,另一個切片的值也會被修改,原因是因為這兩個切片的地址是一致的,想要做到真正的複製只能使用copy函式
對映
對映:Go中的內建型別,它將一個值和一個鍵關聯起來,底層實現是hash,是一種無序的鍵值對集合,也是引用型別
一些栗子
func main() {
//初始化map
//1.make
map1:=make(map[int]string)
fmt.Println(len(map1)) //0
fmt.Println(map1==nil) //flase make建立引用型別時預設初始化
map1[1]="愛小黃"
map1[0]="愛媽媽"
map1[2]="愛爸爸"
fmt.Println(map1,len(map1)) //len=3,即鍵值對的個數
v,ok:=map1[0]
fmt.Println(v,ok) //v 是value ,ok 是判斷是否存在的bool值
delete(map1,0)//刪除map1為0的索引值
fmt.Println(map1)
//2.:map的方式初始化Map
map2:=map[int]string{1:"愛你"}
fmt.Println(map2)
//map是不能拷貝的,我們想擁有一個一模一樣的map只能用for range然後賦值的方式
}
注意:
-
map列印的時候是無序輸出的,因為底層實現是hash
-
刪除Map中的某一個值,使用delete函式
-
Map不能使用copy函式,想要進行Map的複製只能通過for range的方式手動賦值
-
無論是slice array還是map等資料型別,我們在宣告的時候都是沒有佔據記憶體的,也就是並沒有例項化,而如果我們使用Make函式,哪怕cap是0,也是已經分配記憶體了的
-