1. 程式人生 > 其它 >Go語言基礎之陣列 切片和對映

Go語言基礎之陣列 切片和對映

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,也是已經分配記憶體了的