亚洲熟女综合色一区二区三区,亚洲精品中文字幕无码蜜桃,亚洲va欧美va日韩va成人网,亚洲av无码国产一区二区三区,亚洲精品无码久久久久久久

Go 語言中的切片

本位主要介紹一下 Go 語言中可變長度的"數(shù)組"——切片(slice)。數(shù)組有數(shù)組的用處,但是其不可變長度的特性,注定了在大多場景下不是很受歡迎。在大多數(shù)場景下我們都會選擇更加靈活的切片

 

1. 切片的創(chuàng)建

切片的聲明方式和數(shù)組類似,寫法上看就是聲明一個沒有長度的數(shù)組:var 切片名 []切片類型。其中切片類型可以是切片本身,也就是切片的切片,就構(gòu)成了多維的切片。

切片在使用之前必須要初始化,它沒有零值。聲明后它的值是?nil,這是因為它的底層實現(xiàn)是一個指向數(shù)組的指針,在你給它存入一個數(shù)組的地址之前,它只能是?nil。

代碼示例

代碼塊
  • 1? package main
  • 2
  • 3? import (
  • 4? ? ? ? ? ? "fmt"
  • 5? )
  • 6
  • 7? func main() {
  • 8? ? ? ? ? ? var a []int
  • 9? ? ? ? ? ? fmt.Println("初始化前:", a)
  • 10? ? ? ? ??a = make([]int, 5, 10)
  • 11? ? ? ? ? fmt.Println("初始化后:", a)
  • 12? ? ? ? ? a[4] = 5
  • 13? ? ? ? ? fmt.Println(" 賦值后:", a)
  • 14? ? ? ? ? a[5] = 6
  • 15? ? ? ? ? fmt.Println("賦值后:", a)
  • 16? }
  • 第 8 行:聲明一個int類型的切片。
  • 第 10 行:聲明一個長度為5,切片容量為10的切片。其中容量可以不傳,默認會和長度相等。長度為切片真正有值的位置,會初始化零值。
  • 第 12 行:給切片的第 5 個位置賦值。
  • 第 14 行:給切片的第 6 個位置賦值,但是切片的長度為5,所以會報越界的錯誤。

執(zhí)行結(jié)果

圖片描述

 

2. 切片的截取

切片之所以被叫做切片是有原因的,它可以從任意長度開始切,切到任意長度為止,然后這一段拿出來就是一個新的切片。切割形式為切片名(s)[起始下標(begin):結(jié)束下標(end):最大容量(max)]。

Tips:截取到的切片包含起始下標(begin),不包含結(jié)束下標(end)。

切片截取形式表

操作 含義
s[begin??max] 截取切片s從begin到end的數(shù)據(jù),構(gòu)成一個容量為max-begin,長度為begin-end的切片。(用的不多)
s[begin:end] 截取切片s從begin到end的數(shù)據(jù),構(gòu)成一個容量和長度均為begin-end的切片。
s[begin:] 截取切片s從begin到最后的數(shù)據(jù),構(gòu)成一個容量和長度均為len(s)-end的切片。
s[:end] 截取切片s從0到最后的數(shù)據(jù),構(gòu)成一個容量和長度均為end-0的切片。

代碼示例

代碼塊
  • 1? package main
  • 2
  • 3? import (
  • 4? ? ? ? ? ? "fmt"
  • 5? )
  • 6
  • 7? func main() {
  • 8? ? ? ? ? var a = []int{1, 2, 3, 4, 5}
  • 9? ? ? ? ? fmt.Println("a[1:3]=", a[1:3])
  • 10? ? ? ? fmt.Println("a[1:]=", a[1:])
  • 11? ? ? ? fmt.Println("a[:3]=", a[:3])
  • 12? }
  • 第 8 行:直接定義一個值為?[1,2,3,4,5]?的切片,切片長度和容量會根據(jù)切片的值自動生成。例如本行代碼定義的切片就是長度和容量均為5。
  • 第 9 行:取切片下標從1開始到3之前的值,生成新切片。
  • 第 10 行:取切片下標從1開始到最后的值,生成新切片。
  • 第 11 行:取切片下標從0開始到3的值,生成新切片。

執(zhí)行結(jié)果

圖片描述

 

3. 切片的追加

切片使用一個 Go 語言的內(nèi)置函數(shù)append(切片,待添加的值),來進行切片末尾元素的追加。

代碼示例

代碼塊
  • 1? package main
  • 2
  • 3? import (
  • 4? ? ? ? ? "fmt"
  • 5? )
  • 6
  • 7? func main() {
  • 8? ? ? ? ? var a = []int{1, 2, 3, 4, 5}
  • 9? ? ? ? ? a = append(a, 6)
  • 10? ? ? ? fmt.Println(a)
  • 11? ? ? ? a = append(a, 7, 8)
  • 12? ? ? ? fmt.Println(a)
  • 13? ? ? ? b := []int{9, 10}
  • 14? ? ? ? a = append(a, b...)
  • 15? ? ? ? fmt.Println(a)
  • 16? }
  • 第 9 行:在切片 a 的末尾追加一個元素 6。
  • 第 11 行:在切片 a 的末尾連續(xù)追加兩個元素 7 和 8。append?中待添加的值可以是?多個,其中使用?,?隔開。
  • 第 14 行:在切片 a 的末尾追加切片 b。當 append 中待添加的元素是一個數(shù)組或者切片時,在其后面添加?...?就可以全部追加到切片末尾。

執(zhí)行結(jié)果

圖片描述

 

4. 切片的長度和容量

在切片中可以使用len()獲取切片中元素的數(shù)量,也就是切片的長度。使用cap()可以獲取切片引用的數(shù)組的長度,也就切片的容量。切片的容量一般大于等于長度,容量會隨著長度的增長而增長。

在初始化一個切片的時候其實時給切片引用了一個數(shù)組,然后容量就是這個數(shù)組的長度,然后如果切片的長度超過了切片的容量,它就會讓切片引用一個容量更大數(shù)組來存放這些元素。

代碼塊
  • 1? package main
  • 2
  • 3? import (
  • 4? ? ? ? ? "fmt"
  • 5? )
  • 6
  • 7? func main() {
  • 8? ? ? ? ? var a = []int{1, 2, 3, 4, 5}
  • 9? ? ? ? ? fmt.Printf("a的地址%p,a的長度%d,a的容量%dn", a, len(a), cap(a))
  • 10? ? ? ? a = append(a, 6)
  • 11? ? ? ? fmt.Printf("a的地址%p,a的長度%d,a的容量%dn", a, len(a), cap(a))
  • 12? ? ? ? a = append(a, 7, 8)
  • 13? ? ? ? fmt.Printf("a的地址%p,a的長度%d,a的容量%dn", a, len(a), cap(a))
  • 14? ? ? ? b := []int{9, 10, 11}
  • 15? ? ? ? a = append(a, b...)
  • 16? ? ? ? fmt.Printf("a的地址%p,a的長度%d,a的容量%dn", a, len(a), cap(a))
  • 17? }

執(zhí)行結(jié)果

圖片描述

從執(zhí)行結(jié)果可以看到,在切片a每次添加的元素要超過它的容量時,它的地址就會發(fā)生改變,其實就是讓它引用了一個新的容量更大的數(shù)組。

 

5. 小結(jié)

本文主要介紹了切片的使用,有以下注意事項:

  • 切片在使用前需要初始化;
  • 切片的本質(zhì)是一個指針數(shù)組,但是它的地址會隨著長度超過容量而改變;
  • 在應用場景中一般都使用切片。

文章來源于網(wǎng)絡(luò),侵刪!

相關(guān)新聞

歷經(jīng)多年發(fā)展,已成為國內(nèi)好評如潮的Linux云計算運維、SRE、Devops、網(wǎng)絡(luò)安全、云原生、Go、Python開發(fā)專業(yè)人才培訓機構(gòu)!