婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > Go基礎Slice教程詳解

Go基礎Slice教程詳解

熱門標簽:惠州電銷防封電話卡 黃岡人工智能電銷機器人哪個好 阿里云ai電話機器人 汕頭小型外呼系統 浙江高頻外呼系統多少錢一個月 釘釘有地圖標注功能嗎 建造者2地圖標注 濱州自動電銷機器人排名 鄭州亮點科技用的什么外呼系統

Go 語言切片(Slice)

Go 語言切片是對數組的抽象。

Go 數組的長度不可改變,在特定場景中這樣的集合就不太適用,Go中提供了一種靈活,功能強悍的內置類型切片("動態數組"),與數組相比切片的長度是不固定的,可以追加元素,在追加時可能使切片的容量增大。

聲明Slice

帶有 T 類型元素的切片由 []T 表示,其中T代表slice中元素的類型。切片在內部可由一個結構體類型表示,形式如下:

type slice struct { 
 Length  int
 Capacity  int
 ZerothElement *byte
}

可見一個slice由三個部分構成:指針、長度和容量。指針指向第一個slice元素對應的底層數組元素的地址。長度對應slice中元素的數目;長度不能超過容量,容量一般是從slice的開始位置到底層數據的結尾位置。通過len和cap函數分別返回slice的長度和容量。

創建Slice

直接聲明創建 slice

[]元素類型>{元素1, 元素2, …}

創建一個有 3 個整型元素的數組,并返回一個存儲在 c 中的切片引用。

c := []int{6, 7, 8}

make() 函數創建 slice

s1 := make([]int, 5) //長度和容量都是 5
 s2 := make([]int, 3, 10) //長度是3,容量是10
 fmt.Println(cap(s1),s2)

基于底層數組數組或切片創建

基于現有的切片或者數組創建,使用[i:j]這樣的操作符即可,她表示以i索引開始,到j索引結束,截取原數組或者切片,創建而成的新切片,新切片的值包含原切片的i索引,但是不包含j索引。注意i和j都不能超過原切片或者數組的索引

slice :=[]int{1,2,3,4,5}
 slice1 := slice[:]
 slice2 := slice[0:]
 slice3 := slice[:5]
 fmt.Println(slice1)
 fmt.Println(slice2)
 fmt.Println(slice3)

新的切片和原數組或原切片共用的是一個底層數組,所以當修改的時候,底層數組的值就會被改變,所以原切片的值也改變了。

slice := []int{1, 2, 3, 4, 5}
 newSlice := slice[1:3]
 newSlice[0] = 10
 fmt.Println(slice)
 fmt.Println(newSlice)

切片與數組的區別

1.切片不是數組,但是切片底層指向數組

2.切片本身長度是不一定的因此不可以比較,數組是可以的。

3.切片是變長數組的替代方案,可以關聯到指向的底層數組的局部或者全部。

4.切片是引用傳遞(傳遞指針地址),而數組是值傳遞(拷貝值)

5.切片可以直接創建,引用其他切片或數組創建

6.如果多個切片指向相同的底層數組,其中一個值的修改會影響所有的切片

切片的修改

切片自己不擁有任何數據。它只是底層數組的一種表示。對切片所做的任何修改都會反映在底層數組中。

package main
import (
 "fmt"
)
func main() {
 arr := [...]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
 slice := arr[2:5]
 fmt.Println("array before", arr)
 for i := range slice {
  slice[i]++
 }
 fmt.Println("array after ", arr)
}

在上述程序的第 9 行,我們根據數組索引 2,3,4 創建一個切片 dslice 。for 循環將這些索引中的值逐個遞增。當我們使用 for 循環打印數組時,我們可以看到對切片的更改反映在數組中。該程序的輸出是

array before [0 1 2 3 4 5 6 7 8 9]
array after [0 1 3 4 5 5 6 7 8 9]

當多個切片共用相同的底層數組時,每個切片所做的更改將反映在數組中。

package main
import (
 "fmt"
)
func main() {
 array := [4]int{10, 20 ,30, 40}
 slice1 := array[:]
 slice2 := array[:]
 fmt.Println("array before change:", array)
 slice1[0] = 60
 fmt.Println("array after modification to slice slice1:", array)
 slice2[1] = 70
 fmt.Println("array after modification to slice slice2:", array)
}

在 9 行中, numa [:] 缺少開始和結束值。開始和結束的默認值分別為 0 和 len (numa) 。兩個切片 nums1 和 nums2 共享相同的數組。該程序的輸出是

array before change: [10 20 30 40]
array after modification to slice slice1: [60 20 30 40]
array after modification to slice slice2: [60 70 30 40]

從輸出中可以清楚地看出,當切片共享同一個數組時,每個所做的修改都會反映在數組中。

切片的長度和容量

切片的長度是切片中的元素數。 切片的容量是從創建切片索引開始的底層數組中元素數。

package main
import (
 "fmt"
)
func main() {
 fruitarray := [...]string{"apple", "orange", "grape", "mango", "water melon", "pine apple", "chikoo"}
 fruitslice := fruitarray[1:3]
 fmt.Printf("length of slice %d capacity %d", len(fruitslice), cap(fruitslice)) // length of is 2 and capacity is 6
}

在上面的程序中, fruitslice 是從 fruitarray 的索引 1 和 2 創建的。 因此, fruitlice 的長度為 2 。

fruitarray 的長度是 7。 fruiteslice 是從 fruitarray 的索引 1 創建的。因此, fruitslice 的容量是從 fruitarray 索引為 1 開始,也就是說從 orange 開始,該值是 6 。因此, fruitslice 的容量為 6。該程序]輸出切片的 **長度為 2 容量為 6 **。

切片可以重置其容量。任何超出這一點將導致程序運行時拋出錯誤。

package main
import (
 "fmt"
)
func main() {
 fruitarray := [...]string{"apple", "orange", "grape", "mango", "water melon", "pine apple", "chikoo"}
 fruitslice := fruitarray[1:3]
 fmt.Printf("length of slice %d capacity %d\n", len(fruitslice), cap(fruitslice)) // length of is 2 and capacity is 6
 fruitslice = fruitslice[:cap(fruitslice)] // re-slicing furitslice till its capacity
 fmt.Println("After re-slicing length is",len(fruitslice), "and capacity is",cap(fruitslice))
}

在上述程序的第 11 行中, fruitslice 的容量是重置的。以上程序輸出為,

length of slice 2 capacity 6 
After re-slicing length is 6 and capacity is 6

追加切片元素

正如我們已經知道數組的長度是固定的,它的長度不能增加。 切片是動態的,使用 append 可以將新元素追加到切片上。append 函數的定義是

func append(s[]T,x ... T)[]T

append可以直接在切片尾部追加元素,也可以將一個切片追加到另一個切片尾部。

package main
import (
 "fmt"
)
func main() {
 str := []string{"a", "b", "c"}
 fmt.Println("strs:", str, " length:", len(str), "capacity:", cap(str))
 str = append(str, "d")
 fmt.Println("strs:", str, " length:", len(str), " capacity:", cap(str))
}

在上述程序中, str 的容量最初是 3。在第 10 行,我們給 str 添加了一個新的元素,并把 append(str, "d") 返回的切片賦值給 str?,F在 str 的容量翻了一番,變成了 6。

strs: [a b c] length: 3 capacity: 3
strs: [a b c d] length: 4 capacity: 6

切片類型的零值為 nil 。一個 nil 切片的長度和容量為 0??梢允褂?append 函數將值追加到 nil 切片。

package main
import ( 
 "fmt"
)
func main() { 
 var strs []string //zero value of a slice is nil
 if strs == nil {
  fmt.Println("slice is nil going to append")
  strs = append(strs, "a", "b", "c")
  fmt.Println("string contents:",strs)
 }
}

在上面的程序 names 是 nil,我們已經添加 3 個字符串給 names 。該程序的輸出是

slice is nil going to append
string contents: [a b c]

也可以使用 ... 運算符將一個切片添加到另一個切片。

package main
import (
  "fmt"
)
func main() {
  veggies := []string{"potatoes", "tomatoes", "brinjal"}
  fruits := []string{"oranges", "apples"}
  food := append(veggies, fruits...)
  fmt.Println("food:",food)
}

在上述程序的第 10 行,food 是通過 append(veggies, fruits...) 創建。程序的輸出為 food: [potatoes tomatoes brinjal oranges apples]

特別需要注意的是如果新切片的長度未超過源切片的容量,則返回源切片,如果追加后的新切片長度超過源切片的容量,則會返回全新的切片。

func main() {
  s1 := []int{1,2,3,4,5}
  fmt.Printf("s1:%p %d %d %v\n",s1,len(s1),cap(s1),s1)
  s2 :=append(s1,6)
  fmt.Printf("s3:%p %d %d %v\n",s2,len(s2),cap(s2),s2)
  s3 := s1[0:4]
  fmt.Printf("s3:%p %d %d %v\n",s3,len(s3),cap(s3),s3)
  s4 := append(s3,6)
  fmt.Printf("s4:%p %d %d %v\n",s4,len(s4),cap(s4),s4)
  fmt.Printf("s1:%p %d %d %v\n",s1,len(s1),cap(s1),s1)
  s5 := append(s4,8)
  fmt.Printf("s5:%p %d %d %v\n",s5,len(s5),cap(s5),s5)
}

切片的函數傳遞

切片包含長度、容量和指向數組第零個元素的指針。當切片傳遞給函數時,即使它通過值傳遞,指針變量也將引用相同的底層數組。因此,當切片作為參數傳遞給函數時,函數內所做的更改也會在函數外可見。

package main
import (
  "fmt"
)
func subtactOne(numbers []int) {
  for i := range numbers {
    numbers[i] -= 2
  }
}
func main() {
  nos := []int{8, 7, 6}
  fmt.Println("slice before function call", nos)
  subtactOne(nos)                // function modifies the slice
  fmt.Println("slice after function call", nos) // modifications are visible outside
}

上述程序的行號 17 中,調用函數將切片中的每個元素遞減 2。在函數調用后打印切片時,這些更改是可見的。如果你還記得,這是不同于數組的,對于函數中一個數組的變化在函數外是不可見的。

array before function call [8 7 6] 
array after function call [6 5 4]

多維切片

類似于數組,切片可以有多個維度。

package main
import (
  "fmt"
)
func main() { 
   pls := [][]string {
      {"C", "C++"},
      {"JavaScript"},
      {"Go", "Rust"},
      }
  for _, v1 := range pls {
    for _, v2 := range v1 {
      fmt.Printf("%s ", v2)
    }
    fmt.Printf("\n")
  }
}

程序的輸出為,

C C++ 
JavaScript 
Go Rust
copy

切片持有對底層數組的引用。只要切片在內存中,數組就不能被垃圾回收。在內存管理方面,這是需要注意的。讓我們假設我們有一個非常大的數組,我們只想處理它的一小部分。然后,我們由這個數組創建一個切片,并開始處理切片。這里需要重點注意的是,在切片引用時數組仍然存在內存中。

一種解決方法是使用copy 函數 來生成一個切片的副本。這樣我們可以使用新的切片,原始數組可以被垃圾回收。

func copy(dst,src[]T)int`
package main
import (
  "fmt"
)
func main() {
  s1 :=[]int{1,2,3,4,5}
  fmt.Println("s1",s1)
  s2 := make([]int,len(s1))
  fmt.Println("s2",s2)
  copy(s2,s1)
  fmt.Println("s2",s2)
  s3 :=make([]int,len(s1)-2)
  copy(s3,s1);
  fmt.Println("s3",s3)
  s4 :=make([]int,len(s1)-1)
  copy(s4[1:3],s1[2:4]);
  fmt.Println("s4",s4)
}

打印結果:

s1 [1 2 3 4 5]
s2 [0 0 0 0 0]
s2 [1 2 3 4 5]
s3 [1 2 3]
s4 [0 3 4 0]

總結

以上所述是小編給大家介紹的Go基礎Slice教程詳解,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網站的支持!

您可能感興趣的文章:
  • 深入理解golang的基本類型排序與slice排序
  • 深入解析Go語言編程中slice切片結構
  • Go語言入門教程之Arrays、Slices、Maps、Range操作簡明總結
  • Go語言中的Slice學習總結
  • 理解Golang中的數組(array)、切片(slice)和map
  • Go語言中的Array、Slice、Map和Set使用詳解

標簽:瀘州 晉中 滄州 駐馬店 泰安 東營 昭通 阿壩

巨人網絡通訊聲明:本文標題《Go基礎Slice教程詳解》,本文關鍵詞  基礎,Slice,教程,詳解,基礎,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《Go基礎Slice教程詳解》相關的同類信息!
  • 本頁收集關于Go基礎Slice教程詳解的相關信息資訊供網民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    99精品国产一区二区三区不卡| 国产精品国产三级国产普通话蜜臀 | 91精品欧美综合在线观看最新| 亚洲精品写真福利| 久久奇米777| 欧美日韩国产综合视频在线观看| 亚洲一区二区在线观看视频| 国产精品网友自拍| 国产日韩欧美高清在线| 欧美大片在线观看一区二区| 成人av午夜电影| 韩国理伦片一区二区三区在线播放| 亚洲高清免费在线| 亚洲天堂成人网| 中文字幕乱码久久午夜不卡 | 日韩精品欧美精品| 欧美人牲a欧美精品| 欧美性欧美巨大黑白大战| 色视频欧美一区二区三区| 成人av免费网站| 99视频热这里只有精品免费| eeuss鲁片一区二区三区在线看| 国产成人综合在线| 精品国产免费人成电影在线观看四季| 91视频国产资源| 91久久一区二区| 制服丝袜亚洲精品中文字幕| 精品国产三级a在线观看| 国产亚洲成av人在线观看导航 | 美女网站视频久久| 寂寞少妇一区二区三区| 久久99国产精品久久| 高清国产一区二区| 色美美综合视频| 91精品国产麻豆国产自产在线 | 狠狠色丁香久久婷婷综| 成人免费黄色在线| 北岛玲一区二区三区四区| 欧美伦理视频网站| 国产精品久久久久久久久动漫 | 日韩欧美中文字幕一区| 国产欧美日韩在线| 婷婷丁香激情综合| 成人性视频网站| 欧美三级午夜理伦三级中视频| 捆绑变态av一区二区三区| 免费欧美高清视频| 色噜噜狠狠成人网p站| 精品国产网站在线观看| 三级精品在线观看| 北岛玲一区二区三区四区| 日韩美女在线视频 | 欧美撒尿777hd撒尿| 精品国产乱码久久久久久1区2区| 一区二区三区中文字幕电影| 国产精品一区二区免费不卡| 欧美精品粉嫩高潮一区二区| 国产精品情趣视频| 顶级嫩模精品视频在线看| 26uuu另类欧美| 国产成人免费视频一区| 久久日韩粉嫩一区二区三区| 久久99这里只有精品| 欧美一级在线观看| 亚洲国产va精品久久久不卡综合| 91在线视频免费91| 亚洲丝袜制服诱惑| 国产大片一区二区| 亚洲精品你懂的| 国产精品护士白丝一区av| 国产传媒欧美日韩成人| 中文字幕高清不卡| 99久久久国产精品免费蜜臀| 日本一区二区成人| 欧美三级资源在线| 日韩成人精品在线观看| 日韩午夜精品电影| 成人在线视频一区二区| 一区二区在线免费| 精品嫩草影院久久| 国产aⅴ综合色| 亚洲一区日韩精品中文字幕| 亚洲精品在线观| 色哟哟亚洲精品| 麻豆精品视频在线| 国产精品欧美久久久久一区二区| 一本高清dvd不卡在线观看| 久久99久国产精品黄毛片色诱| 亚洲欧美日韩久久精品| 欧美日韩亚洲丝袜制服| 成人午夜激情片| 青青草原综合久久大伊人精品优势| 精品1区2区在线观看| 91精品午夜视频| 972aa.com艺术欧美| 激情av综合网| 亚洲成人自拍偷拍| 中文字幕第一区| 久久综合一区二区| 91精品国产综合久久精品| 成人小视频在线| 久久狠狠亚洲综合| 天天色天天爱天天射综合| 最新国产成人在线观看| 久久你懂得1024| 日韩视频一区二区三区 | 日韩三级精品电影久久久| 日本韩国欧美三级| 欧美在线一二三| 欧美性受xxxx| 成人黄色在线网站| 国产一区高清在线| 紧缚奴在线一区二区三区| 久久国产精品区| 欧美剧情电影在线观看完整版免费励志电影 | 久久久国产一区二区三区四区小说 | 亚洲成人第一页| 国产91精品免费| 成人久久视频在线观看| 国产一区二区免费视频| 美腿丝袜在线亚洲一区| 激情综合色综合久久综合| 丁香婷婷综合五月| 在线免费观看日韩欧美| 99久久99精品久久久久久| 91农村精品一区二区在线| 在线不卡中文字幕播放| 久久精品视频一区二区三区| 国产精品国产三级国产a| 亚洲一区国产视频| 狠狠久久亚洲欧美| 欧美日韩视频在线观看一区二区三区| 日韩欧美一二三| 亚洲欧美色一区| 国产一区二区日韩精品| 99re视频精品| 国产欧美va欧美不卡在线| 偷偷要91色婷婷| 一本一道综合狠狠老| 国产精品拍天天在线| 日日骚欧美日韩| 欧美视频日韩视频| 亚洲色图另类专区| 粉嫩av一区二区三区| 国产人伦精品一区二区| 男女性色大片免费观看一区二区| 色狠狠色噜噜噜综合网| 国产婷婷一区二区| 国产偷国产偷精品高清尤物 | 99久久国产综合色|国产精品| 日韩欧美电影在线| 亚洲一级二级三级| 欧美日韩精品一区二区天天拍小说| 日韩毛片精品高清免费| 97se亚洲国产综合在线| 伊人夜夜躁av伊人久久| 欧美日韩黄色影视| 日韩二区在线观看| 精品国产一二三区| 99久久国产综合精品色伊 | 日韩欧美一区二区久久婷婷| 韩国三级电影一区二区| 日本一区二区电影| 3d动漫精品啪啪一区二区竹菊| 视频一区视频二区中文| 国产情人综合久久777777| 不卡一区二区三区四区| 日韩高清欧美激情| 国产精品蜜臀在线观看| 欧美高清视频一二三区 | 欧美一区二区三区视频在线观看| 激情五月激情综合网| 日本一区二区免费在线观看视频| 99re热这里只有精品免费视频| 亚洲成在线观看| 国产日产欧产精品推荐色| 欧美日产国产精品| 91免费观看视频| 日韩国产在线一| 亚洲人快播电影网| 精品久久五月天| 中文字幕av一区二区三区免费看| 欧美年轻男男videosbes| 色诱视频网站一区| av成人免费在线观看| 国产成人免费视频网站| 极品美女销魂一区二区三区 | 久久精品这里都是精品| 精品人伦一区二区色婷婷| 日韩免费高清av| 欧美一卡2卡三卡4卡5免费| 欧美三级日韩三级国产三级| 91麻豆免费观看| 91久久线看在观草草青青| 国产福利91精品一区二区三区| 免费xxxx性欧美18vr| 日韩精品久久久久久| 亚洲成人激情社区| 日韩av一区二区三区| 国模少妇一区二区三区|