go基礎——03(array、slice、map)

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
學習筆記
1、arrayarray就是數組,它的定義方式如下:var arr [n]type在[n]type中,n表示數組的長度,type表示儲存元素的類型。對數組的操作和其它語言類似,都是通過[]來進行讀取或賦值:
var arr [10]int // 聲明了一個int類型的數組
arr[0] = 42 // 數組下標是從0開始的
arr[1] = 13 // 賦值操作
fmt.Printf("The first element is %d\n", arr[0]) // 擷取資料,返回42
fmt.Printf("The last element is %d\n", arr[9]) //返回未賦值的最後一個元素,預設返回0
由於長度也是數群組類型的一部分,因此[3]int與 [4]int是不同的類型,數組也就不能改變長度。數組之間的賦值是值的賦值,即當把一個數組作為參數傳入函數的時候,傳入的其實是該數組的副本,而不是它的指標。如果要使用指標,那麼就需要用到後面介紹的slice類型了。數組可以使用另一種:=來聲明
a := [3]int{1, 2, 3} // 聲明了一個長度為3的int數組
b := [10]int{1, 2, 3} // 聲明了一個長度為10的int數組,其中前三個元素初始化為1、2、3,其它預設為0
c := [...]int{4, 5, 6} // 可以省略長度而採用`...`的方式,Go會自動根據元素個數來計算長度
也許你會說,我想數組裡面的值還是數組,能實現嗎?當然咯,Go支援嵌套數組,即多維陣列。比如下面的代碼就聲明了一個二維數組:
// 聲明了一個二維數組,該數組以兩個數組作為元素,其中每個數組中又有4個int類型的元素
doubleArray := [2][4]int{[4]int{1, 2, 3, 4}, [4]int{5, 6, 7, 8}}
// 如果內部的元素和外部的一樣,那麼上面的聲明可以簡化,直接忽略內部的類型
easyArray := [2][4]int{{1, 2, 3, 4}, {5, 6, 7, 8}}

2、slice在很多應用情境中,數組並不能滿足我們的需求。在初始定義數組時,我們並不知道需要多大的數組,因此我們就需要“動態數組”。在Go裡面這種資料結構叫sliceslice並不是真正意義上的動態數組,而是一個參考型別。slice總是指向一個底層array,slice的聲明也可以像array一樣,只是不需要長度。// 和聲明array一樣,只是少了長度var fslice []int接下來我們可以聲明一個slice,並初始化資料,如下所示:slice := []byte {'a', 'b', 'c', 'd'}slice可以從一個數組或一個已經存在的slice中再次聲明。slice通過array[i:j]來擷取,其中i是數組的開始位置,j是結束位置,但不包含array[j],它的長度是j-i。
// 聲明一個含有10個元素元素類型為byte的數組
var ar = [10]byte {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'}
// 聲明兩個含有byte的slice
var a, b []byte
// a指向數組的第3個元素開始,併到第五個元素結束,
a = ar[2:5]    //現在a含有的元素: ar[2]、ar[3]和ar[4] 
// b是數組ar的另一個slice
b = ar[3:5]    // b的元素是:ar[3]和ar[4] 
注意slice和數組在聲明時的區別:聲明數組時,方括弧內寫明了數組的長度或使用...自動計算長度,而聲明slice時,方括弧內沒有任何字元。
slice有一些簡便的操作
  • slice的預設開始位置是0,ar[:n]等價於ar[0:n]
  • slice的第二個序列預設是數組的長度,ar[n:]等價於ar[n:len(ar)]
  • 如果從一個數組裡面直接擷取slice,可以這樣ar[:],因為預設第一個序列是0,第二個是數組的長度,即ar[:]等價於ar[0:len(ar)]
對於slice有幾個有用的內建函數:
  •     len 擷取slice的長度
  •     cap 擷取slice的最大容量
  •     append 向slice裡面追加一個或者多個元素
  •     copy 函數copy從源slice的src中複製元素到目標dst,並且返回複製的元素的個數
註: append函數會改變slice所引用的數組的內容,從而影響到引用同一數組的其它slice。 但當slice中沒有剩餘空間(即(cap-len) == 0)時,此時將動態分配新的數組空間。返回的slice數組指標將指向這個空間,而原數組的內容將保持不變;其它引用此數組的slice則不受影響。
下面這個例子展示了更多關於slice的操作:
// 聲明一個數組
var array = [10]byte{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'}
// 聲明兩個slice
var aSlice, bSlice []byte
// 示範一些簡便操作
aSlice = array[:3] // 等價於aSlice = array[0:3] aSlice包含元素: a,b,c
aSlice = array[5:] // 等價於aSlice = array[5:10] aSlice包含元素: f,g,h,i,j
aSlice = array[:] // 等價於aSlice = array[0:10] 這樣aSlice包含了全部的元素
// 從slice中擷取slice
aSlice = array[3:7] // aSlice包含元素: d,e,f,g,len=4,cap=7
bSlice = aSlice[1:3] // bSlice 包含aSlice[1], aSlice[2] 也就是含有: e,f
bSlice = aSlice[:3] // bSlice 包含 aSlice[0], aSlice[1], aSlice[2] 也就是含有: d,e,f
bSlice = aSlice[0:5] // 對slice的slice可以在cap範圍內擴充,此時bSlice包含:d,e,f,g,h
bSlice = aSlice[:] // bSlice包含所有aSlice的元素: d,e,f,g

slice是參考型別,所以當引用改變其中元素的值時,其它的所有引用都會改變該值,例如上面的aSlice和bSlice,如果修改了aSlice中元素的值,那麼bSlice相對應的值也會改變。從概念上面來說slice像一個結構體,這個結構體包含了三個元素: 
  •     - 指標,指向數組中slice指定的開始位置 
  •     - 長度,即slice的長度
  •     - 最大長度,也就是slice開始位置到數組的最後位置的長度
3、map格式為:    map[keyType]valueTypemap的讀取和設定也類似slice一樣,通過key來操作,只是slice的index只能是`int`類 型,而map多了很多類型,可以是int,可以是string及所有完全定義了==與!=操作的類型。 
// 聲明一個key是字串,值為int的字典,這種方式的聲明需要在使用之前使用make初始化var numbers map[string] int// 另一種map的聲明方式numbers := make(map[string]int)numbers["one"] = 1 //賦值numbers["ten"] = 10 //賦值numbers["three"] = 3fmt.Println("第三個數字是: ", numbers["three"]) // 讀取資料// 列印出來如:第三個數字是: 3
這個map就像我們平常看到的表格一樣,左邊列是key,右邊列是值使用map過程中需要注意的幾點:
  •  - map是無序的,每次列印出來的map都會不一樣,它不能通過index擷取,而必須通過key擷取 
  • - map的長度是不固定的,也就是和slice一樣,也是一種參考型別 
  • - 內建的len函數同樣適用於map,返回map擁有的key的數量 
  • - map的值可以很方便的修改,通過numbers["one"]=11可以很容易的把key為one的字典值改為11
map的初始化可以通過key:val的方式初始化值,同時map內建有判斷是否存在key的方式通過delete刪除map的元素:
// 初始化一個字典rating := map[string]float32 {"C":5, "Go":4.5, "Python":4.5, "C++":2 }// map有兩個傳回值,第二個傳回值,如果不存在key,那麼ok為false,如果存在ok為truecsharpRating, ok := rating["C#"]if ok {fmt.Println("C# is in the map and its rating is ", csharpRating)} else {fmt.Println("We have no rating associated with C# in the map")}delete(rating, "C") // 刪除key為C的元素
上面說過了,map也是一種參考型別,如果兩個map同時指向一個底層,那麼一個改變,另一個也相應的改變:
m := make(map[string]string)m["Hello"] = "Bonjour"m1 := mm1["Hello"] = "Salut" // 現在m["hello"]的值已經是Salut了


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.