Go語言開發(三)、Go語言內建容器

來源:互聯網
上載者:User

標籤:com   一點   定義   執行個體   大小   \n   shadow   引用   技術   

Go語言開發(三)、Go語言內建容器一、Go語言數組1、Go語言數組簡介

Go語言提供了數群組類型的資料結構。
數組是具有相同唯一類型的一組已編號且長度固定的資料項目序列,類型可以是任意的原始類型例如×××、字串或者自訂類型。
相對於去聲明number0, number1, ..., and number99的變數,使用數組形式numbers[0], numbers[1] ..., numbers[99]更加方便且易於擴充。
數組元素可以通過索引(位置)來讀取(或者修改),索引從0開始,第一個元素索引為 0,第二個索引為 1,以此類推。

2、Go語言數組聲明

Go 語言數組聲明需要指定元素類型及元素個數,文法格式如下:
var variable_name [SIZE] variable_type
以上為一維數組的定義方式。數組長度必須是整數且大於0。例如以下定義了數組balance長度為10類型為float32:
var balance [10] float32

3、Go語言數組初始化

var balance = [5]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
初始化數組中{}中的元素個數不能大於[]中的數字。
如果忽略[]中的數字不設定數組大小,Go語言會根據元素的個數來設定數組的大小:
var balance = [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
該執行個體與上面的執行個體是一樣的,雖然沒有設定數組的大小。
balance[4] = 50.0
以上執行個體讀取了第五個元素。數組元素可以通過索引(位置)來讀取(或者修改),索引從0開始,第一個元素索引為0,第二個索引為1,以此類推。

4、Go數組元素訪問

數組元素可以通過索引(位置)來讀取。格式為數組名後加中括弧,中括弧中為索引的值。例如:
var salary float32 = balance[9]
以上執行個體讀取了數組balance第10個元素的值。
以下示範了數組完整操作(聲明、賦值、訪問)的執行個體:

package mainimport "fmt"func main() {   var n [10]int /* n 是一個長度為 10 的數組 */   var i,j int   /* 為數組 n 初始化元素 */   for i = 0; i < 10; i++ {      n[i] = i + 100 /* 設定元素為 i + 100 */   }   /* 輸出每個數組元素的值 */   for j = 0; j < 10; j++ {      fmt.Printf("Element[%d] = %d\n", j, n[j] )   }}
5、Go語言多維陣列簡介

Go 語言支援多維陣列,以下為常用的多維陣列聲明方式:
var variable_name [SIZE1][SIZE2]...[SIZEN] variable_type
以下執行個體聲明了三維的整型數組:
var threedim [5][10][4]int

6、Go語言二維數組聲明

二維數組是最簡單的多維陣列,二維數組本質上是由一維數組組成的。二維數組定義方式如下:
var arrayName [ x ][ y ] variable_type
variable_type為Go語言的資料類型,arrayName為數組名,二維數組可認為是一個表格,x為行,y為列,示範了一個二維數組a為三行四列:

二維數組中的元素可通過a[ i ][ j ]來訪問。
初始化二維數組
多維陣列可通過大括弧來初始值。以下執行個體為一個3行4列的二維數組:

a = [3][4]int{{0, 1, 2, 3} ,   /*  第一行索引為 0 */{4, 5, 6, 7} ,   /*  第二行索引為 1 */{8, 9, 10, 11}   /*  第三行索引為 2 */}

訪問二維數組
二維數組通過指定座標來訪問。如數組中的行索引與列索引,例如:
int val = a[2][3]
二維數組可以使用迴圈嵌套來輸出元素:

package mainimport "fmt"func main() {   /* 數組 - 5 行 2 列*/   var a = [5][2]int{ {0,0}, {1,2}, {2,4}, {3,6},{4,8}}   var i, j int   /* 輸出數組元素 */   for  i = 0; i < 5; i++ {      for j = 0; j < 2; j++ {         fmt.Printf("a[%d][%d] = %d\n", i,j, a[i][j] )      }   }}
7、數組參數傳遞

如果向函數傳遞數組參數,需要在函數定義時,聲明形參為數組。數組參數傳遞為值傳遞,如果要在函數內部修改數組的元素的值,需要傳遞數組指標。通常,函數的數組參數的聲明有兩種方式:
A、形參指定數組大小

func sum(arr [5] int, size int) int{   var c int = 0   var i int   for i = 0; i < size;i++{      c += arr[i]   }   return c}

B、形參不指定數組大小

 func getAverage(arr []int,size int) float32 {   var i int   var avg float32   var sum int   for i = 0; i < size; i++{      sum += arr[i]   }   avg = float32(sum / size)   return avg;}

數組使用執行個體:

package mainimport "fmt"func getAverage(arr []int,size int) float32 {   var i int   var avg float32   var sum int   for i = 0; i < size; i++{      sum += arr[i]   }   avg = float32(sum / size)   return avg;}func sum(arr [5] int, size int) int{   var c int = 0   var i int   for i = 0; i < size;i++{      c += arr[i]   }   return c}func main() {   var a [] int   a = []int{1,2,6,90}   var c float32   c = getAverage(a,4)   fmt.Println(c)   var b [5] int   b = [5]int{1,2,3,4,5}   var d int = sum(b,5)   fmt.Println(d)}
二、Go語言切片1、切片定義

Go語言切片是對數組的抽象。
由於Go數組的長度不可改變,Go中提供了一種靈活、功能強悍的內建類型切片("動態數組"),切片的長度是不固定的,可以追加元素,在追加時可能使切片的容量增大。
可以聲明一個未指定大小的數組來定義切片:
var identifier []type
使用make()函數來建立切片:
var slice1 []type = make([]type, len)
可以指定容量,其中capacity為選擇性參數。
make([]T, length, capacity)
len是數組的長度並且也是切片的初始長度。

2、切片初始化

s :=[] int {1,2,3 }
直接初始化切片,[]表示是切片類型,{1,2,3}初始化值依次是1,2,3,cap=len=3
s := arr[:]
使用數組arr的引用初始化切片s
s := arr[startIndex:endIndex]
將arr中從下標startIndex到endIndex-1下的元素建立為一個新的切片
s := arr[startIndex:]
預設endIndex時將表示一直到arr的最後一個元素
s := arr[:endIndex]
預設startIndex時將表示從arr的第一個元素開始
s1 := s[startIndex:endIndex]
通過切片s初始化切片s1
s :=make([]int,len,cap)
通過內建函數make()初始化切片s,[]int標識為其元素類型為int的切片

3、切片操作

切片是可索引的,並且可以由len()方法擷取長度。
切片提供了計算容量的方法cap()可以測量切片最長可以達到多少。

package mainimport "fmt"func printSlice(x []int){   fmt.Printf("len=%d cap=%d slice=%v\n",len(x),cap(x),x)}func main() {   var slice1 [] int   var slice2 [] int = make([]int, 6)   slice1 = []int{1,2,3,4}   slice2 = []int{1,2,3}   printSlice(slice1)   printSlice(slice2)   s :=[] int {1,2,3 }   fmt.Println(s)}
4、nil切片

切片在未初始化前預設為nil,長度為0。

package mainimport "fmt"func printSlice(x []int){   fmt.Printf("len=%d cap=%d slice=%v\n",len(x),cap(x),x)}func main() {   var slice1 [] int   printSlice(slice1)   if slice1 == nil{      fmt.Println("slice1 is nil")   }  }
5、切片截取

可以通過設定下限及上限來設定截取切片[lower-bound:upper-bound]。

package mainimport "fmt"func printSlice(x []int){   fmt.Printf("len=%d cap=%d slice=%v\n",len(x),cap(x),x)}func main() {   //建立切片   numbers := []int{0,1,2,3,4,5,6,7,8}   printSlice(numbers)   //列印原始切片   fmt.Println("numbers ==", numbers)   //列印子切片從索引1(包含) 到索引4(不包含)   fmt.Println("numbers[1:4] ==", numbers[1:4])   //預設下限為0   fmt.Println("numbers[:3] ==", numbers[:3])   //預設上限為 len(s)   fmt.Println("numbers[4:] ==", numbers[4:])   numbers1 := make([]int,0,5)   printSlice(numbers1)   //列印子切片從索引0(包含)到索引2(不包含)   number2 := numbers[:2]   printSlice(number2)   //列印子切片從索引2(包含)到索引5(不包含)   number3 := numbers[2:5]   printSlice(number3)}
6、切片的本質

切片在本質上是數組的視圖。切片是一個數組片段的描述,包含了指向數組的指標、片段的長度和容量(片段的最大長度)。切片與底層數組的關係如下:

切片的內部實現如下:

切片內部包含一個指向底層數組的某個位置的指標、切片長度資訊、切片容量資訊。
slice可以向後擴充,不可以向前擴充。
s[i]方式對切片資料進行引用不可以超越len(s),向後擴充不可以超越底層數組cap(s)。

package mainimport "fmt"func sliceExtend(){   //定義數組   arr := [...]int{0,1,2,3,4,5,6,7}   s1 := arr[2:6]   s2 := s1[3:5]   s3 := arr[2:]   s4 := arr[:6]   s5 := arr[:]   printSlice(s1)//len=4 cap=8 slice=[2 3 4 5]   printSlice(s2)//len=2 cap=5 slice=[5 6]   printSlice(s3)//len=8 cap=8 slice=[2 3 4 5 6 7]   printSlice(s4)//len=6 cap=10 slice=[0 1 2 3 4 5]   printSlice(s5)//len=10 cap=10 slice=[0 1 2 3 4 5 6 7]   //對切片中資料進行修改,底層數組資料也被修改   s1[0] = 100   printSlice(s1)//len=4 cap=8 slice=[100 3 4 5]   printSlice(s5)//len=10 cap=10 slice=[0 1 100 3 4 5 6 7]   fmt.Println(arr)//[0 1 100 3 4 5 6 7]   s1 = s1[2:6]   printSlice(s1)//len=4 cap=6 slice=[4 5 6 7]   //切片不能引用底層數組範圍外的資料   //printSlice(s1[2:9])//報錯}func main() {   sliceExtend()}
7、切片追加和拷貝

如果想增加切片的容量,必須建立一個新的更大的切片並把原分區的內容都拷貝過來。
append()函數可以相一個切片追加一個或多個元素。
copy(dest,src)函數可以將dest切片拷貝到src切片。
追加元素時,如果切片超越了cap,系統會為切片分配一個更大的底層數組,每次需要重新分配底層數組時,底層數組的容量會翻倍增長。

package mainimport "fmt"func sliceOperate() {   var numbers = [3]int{0,1}//數組   s1 := numbers[1:]//切片   s1[0] = 101//修改切片的元素的值   printSlice(s1)//len=2 cap=2 slice=[101 0]   fmt.Println(numbers)//[0 101 0]   //向切片追加一個元素   s1 = append(s1, 2)   printSlice(s1)//len=3 cap=4 slice=[101 0 2]   //向切片添加一個元素,已經超越cap,系統會為切片分配更大的底層數組   s1 = append(s1, 3)   printSlice(s1)//len=4 cap=4 slice=[101 0 2 3]   fmt.Println(numbers)//[0 101 0]   //同時添加多個元素,系統為切片分配新的底層數組   s1 = append(s1, 4,5,6)   printSlice(s1)//len=7 cap=8 slice=[101 0 2 3 4 5 6]   fmt.Println(numbers)//[0 101 0]   //建立切片numbers1,len與numbers切片相同,cap為2倍   s2 := make([]int, len(s1), (cap(s1))*2)   //拷貝numbers的內容到numbers1   copy(s2,s1)   printSlice(s2)//len=7 cap=16 slice=[101 0 2 3 4 5 6]//將s2中的0刪除    s2 = append(s2[0:1], s2[2:]...)    printSlice(s2)//len=6 cap=16 slice=[101 2 3 4 5 6]//刪除第一個元素   front := s2[0]   fmt.Println(front)//101   s3 := s2[1:]   printSlice(s3)//len=5 cap=15 slice=[2 3 4 5 6]   //刪除最後一個元素   tail := s2[len(s2)-1]   s4 := s2[:len(s2) - 1]   fmt.Println(tail)//6   printSlice(s4)//len=5 cap=16 slice=[101 2 3 4 5]}func main() {   sliceOperate()}
三、Go語言Map1、Go語言Map簡介

Ma是一種無序的索引值對的集合。Map最重要的一點是通過key來快速檢索資料。
Map是一種集合,可以對其進行迭代。Map使用hash表來實現,Map是無序的,無法決定返回順序。

2、Go語言Map定義

可以使用內建函數make,也可以使用map關鍵字來定義Map:

//聲明變數,預設map是nilvar map_variable map[key_data_type]value_data_type//使用make函數map_variable := make(map[key_data_type]value_data_type)

如果不初始化map,會建立一個nil的map。nil的map不能用來存放索引值對。

//map集合建立var countryCapitalMap map[string]string//countryCapitalMap==nilcountryCapitalMap = make(map[string]string)//countryCapitalMap == empty map
3、Go語言Map操作

擷取元素:map[key]
key不存在時,獲得value類型的初始值。
用value,ok := map[key]來判斷是否存在key。
使用range遍曆key,遍曆key,value對,遍曆不保證順序。
使用len獲得map的元素個數.
map使用雜湊表,必須可以比較相等。
除了slice、map、function的內建類型都可以作為key。struct類型如果不包含slice、map、func欄位可以作為key。
delete()函數用於刪除集合的元素, 參數為map和其對應的key。

package mainimport "fmt"func mapDemo(){   //map集合建立   var countryCapitalMap map[string]string   countryCapitalMap = make(map[string]string)   //map插入key-value對   countryCapitalMap["France"] = "Paris"   countryCapitalMap["Italy"] = "羅馬"   countryCapitalMap["Japan"] = "東京"   countryCapitalMap["India"] = "新德裡"   //map值的修改   countryCapitalMap["France"] = "巴黎"   //輸出國家首都資訊   for country := range countryCapitalMap {      fmt.Println(country, "首都是", countryCapitalMap [country])   }   //查看元素在集合中是否存在   captial, ok := countryCapitalMap["美國"]   //如果確定是真實的,則存在,否則不存在   if (ok) {      fmt.Println("美國的首都是", captial)   } else {      fmt.Println("美國的首都不存在")   }}func deleteMap(){   //建立map   countryCapitalMap := map[string]string{"France": "Paris", "Italy": "Rome", "Japan": "Tokyo", "India": "New delhi"}   fmt.Println("原始地圖")   //列印地圖   for country := range countryCapitalMap {      fmt.Println(country, "首都是", countryCapitalMap [ country ])   }   //刪除元素   delete(countryCapitalMap, "France")   fmt.Println("法國條目被刪除")   fmt.Println("刪除元素後地圖")   //列印地圖   for country := range countryCapitalMap {      fmt.Println(country, "首都是", countryCapitalMap [ country ])   }}func main() {   mapDemo()   deleteMap()}
四、Go語言range1、range簡介

Go語言中range關鍵字用於for迴圈中迭代數組(array)、切片(slice)、通道(channel)或集合(map)的元素。在數組和切片中,range返回元素的索引和索引對應的值,在集合中返回key-value對的key值。

2、rang使用執行個體
package mainimport "fmt"func rangeDemo(){   //使用range遍曆切片   nums := []int{2, 3, 4}   sum := 0   //返回的切片的索引可以省略   for _, num := range nums {      sum += num   }   fmt.Println("sum:", sum)   //在切片上使用range,返回index和值   for i, num := range nums {      if num == 3 {         fmt.Println("index:", i)      }   }   fmt.Println(sum)   //使用range迭代map   kvs := map[string]string{"a": "apple", "b": "banana"}   for k, v := range kvs {      fmt.Printf("%s -> %s\n", k, v)   }   //使用range遍曆Unicode字串,返回字元的索引與字元(Unicode的值)本身   for i, c := range "go" {      fmt.Println(i, c)   }}func main() {   rangeDemo()   a := map[int]string{1:"hello",2:"world"}   for k,v := range a{   fmt.Println(k,v)}}

Go語言開發(三)、Go語言內建容器

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.