激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

腳本之家,腳本語言編程技術(shù)及教程分享平臺(tái)!
分類導(dǎo)航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服務(wù)器之家 - 腳本之家 - Golang - Go語言中的Slice學(xué)習(xí)總結(jié)

Go語言中的Slice學(xué)習(xí)總結(jié)

2020-04-10 14:32junjie Golang

這篇文章主要介紹了Go語言中的Slice學(xué)習(xí)總結(jié),本文講解了Slice的定義、Slice的長度和容量、Slice是引用類型、Slice引用傳遞發(fā)生“意外”等內(nèi)容,需要的朋友可以參考下

概念

Slice切片是對(duì)底層數(shù)組Array的封裝,在內(nèi)存中的存儲(chǔ)本質(zhì)就是數(shù)組,體現(xiàn)為連續(xù)的內(nèi)存塊,Go語言中的數(shù)組定義之后,長度就已經(jīng)固定了,在使用過程中并不能改變其長度,而Slice就可以看做一個(gè)長度可變的數(shù)組進(jìn)行使用,最為關(guān)鍵的,是數(shù)組在使用的過程中都是值傳遞,將一個(gè)數(shù)組賦值給一個(gè)新變量或作為方法參數(shù)傳遞時(shí),是將源數(shù)組在內(nèi)存中完全復(fù)制了一份,而不是引用源數(shù)組在內(nèi)存中的地址,為了滿足內(nèi)存空間的復(fù)用和數(shù)組元素的值的一致性的應(yīng)用需求,Slice出現(xiàn)了,每個(gè)Slice都是都源數(shù)組在內(nèi)存中的地址的一個(gè)引用,源數(shù)組可以衍生出多個(gè)Slice,Slice也可以繼續(xù)衍生Slice,而內(nèi)存中,始終只有源數(shù)組,當(dāng)然,也有例外,后邊再說。

用法

1.Slice的定義

Slice可以通過兩種方式定義,一種是從源數(shù)組中衍生,一種是通過make函數(shù)定義,本質(zhì)上來說都一樣,都是在內(nèi)存中通過數(shù)組的初始化的方式開辟一塊內(nèi)存,將其劃分為若干個(gè)小塊用來存儲(chǔ)數(shù)組元素,然后Slice就去引用整個(gè)或者局部數(shù)組元素。
直接初始化一個(gè)Slice:

復(fù)制代碼 代碼如下:

 s := []int{1, 2, 3}

 

注意,這與初始化數(shù)組有一點(diǎn)點(diǎn)區(qū)別,有的同學(xué)認(rèn)為這個(gè)寫法是定義和初始化一個(gè)數(shù)組,事實(shí)上這個(gè)寫法是現(xiàn)在內(nèi)存中構(gòu)建一個(gè)包括有3個(gè)元素的數(shù)組,然后將這個(gè)數(shù)組的應(yīng)用賦值給s這個(gè)Slice,通過以下數(shù)組的定義進(jìn)行區(qū)別:

復(fù)制代碼 代碼如下:

 a := [3]int{1, 2, 3}
 b := [...]int{1, 2, 3}
 c := []int{1, 2, 3}
 fmt.Println(cap(a), cap(b), cap(c))
 a = append(a, 4)//Error:first argument to append must be slice; have [3]int
 b = append(b, 4)//Errot:first argument to append must be slice; have [3]int
 c = append(c, 4)//正常,說明變量c是Slice類型

 

可以看出,強(qiáng)調(diào)了數(shù)組定義的規(guī)則:長度和類型必須指定,若是根據(jù)實(shí)際元素個(gè)數(shù)自動(dòng)計(jì)算數(shù)組長度,需要使用[...]定義,而不能只使用[]。

從數(shù)組中切片構(gòu)建Slice:

復(fù)制代碼 代碼如下:

 a := [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}
 s := a[2:8]
 fmt.Println(s) //輸出:[3 4 5 6 7 8]

 

定義一個(gè)數(shù)組a,截取下標(biāo)為2到8之間部分(包括2不包括8),構(gòu)建一個(gè)Slice。

通過make函數(shù)定義:

復(fù)制代碼 代碼如下:

 s := make([]int, 10, 20)
 fmt.Println(s) //輸出:[0 0 0 0 0 0 0 0 0 0]

 

make函數(shù)第一個(gè)參數(shù)表示構(gòu)建的數(shù)組的類型,第二個(gè)參數(shù)為數(shù)組的長度,第三個(gè)參數(shù)可選,是slice的容量,默認(rèn)為第二個(gè)參數(shù)值。

2.Slice的長度和容量

Slice有兩個(gè)比較混淆的概念,就是長度和容量,何謂長度?這個(gè)長度跟數(shù)組的長度是一個(gè)概念,即在內(nèi)存中進(jìn)行了初始化實(shí)際存在的元素的個(gè)數(shù)。何謂容量?如果通過make函數(shù)創(chuàng)建Slice的時(shí)候指定了容量參數(shù),那內(nèi)存管理器會(huì)根據(jù)指定的容量的值先劃分一塊內(nèi)存空間,然后才在其中存放有數(shù)組元素,多余部分處于空閑狀態(tài),在Slice上追加元素的時(shí)候,首先會(huì)放到這塊空閑的內(nèi)存中,如果添加的參數(shù)個(gè)數(shù)超過了容量值,內(nèi)存管理器會(huì)重新劃分一塊容量值為原容量值*2大小的內(nèi)存空間,依次類推。這個(gè)機(jī)制的好處在能夠提升運(yùn)算性能,因?yàn)閮?nèi)存的重新劃分會(huì)降低性能。

復(fù)制代碼 代碼如下:

 a := [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}
 s := a[0:]
 s = append(s, 11, 22, 33)
 sa := a[2:7]
 sb := sa[3:5]
 fmt.Println(a, len(a), cap(a))    //輸出:[1 2 3 4 5 6 7 8 9 0] 10 10
 fmt.Println(s, len(s), cap(s))    //輸出:[1 2 3 4 5 6 7 8 9 0 11 22 33] 13 20
 fmt.Println(sa, len(sa), cap(sa)) //輸出:[3 4 5 6 7] 5 8
 fmt.Println(sb, len(sb), cap(sb)) //輸出:[6 7] 2 5

 

可以看出,數(shù)組的len和cap是永遠(yuǎn)相等的,并且是在定義的時(shí)候就已經(jīng)指定的,不能改變。切片s引用這個(gè)數(shù)組的全部元素,初始長度和容量都為10,繼續(xù)追加3個(gè)元素后,其長度變?yōu)?3容量為20,。切片sa截取下標(biāo)2到7的數(shù)組片段,長度為5,容量為8,這個(gè)容量的改變規(guī)則為原容量值減掉起始下標(biāo),此時(shí)若追加元素,會(huì)覆蓋掉原內(nèi)存地址中存在的值。切片sb截取切片sa下標(biāo)3到5的數(shù)組片段,注意,這里的下標(biāo)指的是sa的下標(biāo),不是源數(shù)組的下標(biāo),長度為2,容量為8-3=5。

3.Slice是引用類型

上邊已經(jīng)提到過,Slice是對(duì)源數(shù)組的一個(gè)引用,改變Slice中的元素的值,實(shí)質(zhì)上就是改變?cè)磾?shù)組的元素的值。

復(fù)制代碼 代碼如下:

 a := [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}
 sa := a[2:7]
 sa = append(sa, 100)
 sb := sa[3:8]
 sb[0] = 99
 fmt.Println(a)  //輸出:[1 2 3 4 5 99 7 100 9 0]
 fmt.Println(sa) //輸出:[3 4 5 99 7 100]
 fmt.Println(sb) //輸出:[99 7 100 9 0]

 

可以看到,不管是append操作,還是賦值操作,都影響了源數(shù)組或者其他引用同一數(shù)組的Slice的元素。Slice進(jìn)行數(shù)組引用的時(shí)候,其實(shí)是將指針指向了內(nèi)存中具體元素的地址,如數(shù)組的內(nèi)存地址,事實(shí)上是數(shù)組中第一個(gè)元素的內(nèi)存地址,Slice也是如此。

 

復(fù)制代碼 代碼如下:

 a := [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 0}
 sa := a[2:7]
 sb := sa[3:8]
 fmt.Printf("%p\n", sa)   //輸出:0xc084004290
 fmt.Println(&a[2], &sa[0])      //輸出:0xc084004290 0xc084004290
 fmt.Printf("%p\n", sb)   //輸出:0xc0840042a8
 fmt.Println(&a[5], &sb[0])      //輸出:0xc0840042a8 0xc0840042a8

 

4.Slice引用傳遞發(fā)生“意外”

上邊我們一直在說,Slice是引用類型,指向的都是內(nèi)存中的同一塊內(nèi)存,不過在實(shí)際應(yīng)用中,有的時(shí)候卻會(huì)發(fā)生“意外”,這種情況只有在像切片append元素的時(shí)候出現(xiàn),Slice的處理機(jī)制是這樣的,當(dāng)Slice的容量還有空閑的時(shí)候,append進(jìn)來的元素會(huì)直接使用空閑的容量空間,但是一旦append進(jìn)來的元素個(gè)數(shù)超過了原來指定容量值的時(shí)候,內(nèi)存管理器就是重新開辟一個(gè)更大的內(nèi)存空間,用于存儲(chǔ)多出來的元素,并且會(huì)將原來的元素復(fù)制一份,放到這塊新開辟的內(nèi)存空間。

復(fù)制代碼 代碼如下:

 a := []int{1, 2, 3, 4}
 sa := a[1:3]
 fmt.Printf("%p\n", sa) //輸出:0xc0840046e0
 sa = append(sa, 11, 22, 33)
 fmt.Printf("%p\n", sa) //輸出:0xc084003200

 

可以看到執(zhí)行了append操作后,內(nèi)存地址發(fā)生了變化,說明已經(jīng)不是引用傳遞。

延伸 · 閱讀

精彩推薦
  • GolangGolang中Bit數(shù)組的實(shí)現(xiàn)方式

    Golang中Bit數(shù)組的實(shí)現(xiàn)方式

    這篇文章主要介紹了Golang中Bit數(shù)組的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧...

    天易獨(dú)尊11682021-06-09
  • Golanggolang的httpserver優(yōu)雅重啟方法詳解

    golang的httpserver優(yōu)雅重啟方法詳解

    這篇文章主要給大家介紹了關(guān)于golang的httpserver優(yōu)雅重啟的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,...

    helight2992020-05-14
  • Golanggo日志系統(tǒng)logrus顯示文件和行號(hào)的操作

    go日志系統(tǒng)logrus顯示文件和行號(hào)的操作

    這篇文章主要介紹了go日志系統(tǒng)logrus顯示文件和行號(hào)的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧...

    SmallQinYan12302021-02-02
  • GolangGolang通脈之?dāng)?shù)據(jù)類型詳情

    Golang通脈之?dāng)?shù)據(jù)類型詳情

    這篇文章主要介紹了Golang通脈之?dāng)?shù)據(jù)類型,在編程語言中標(biāo)識(shí)符就是定義的具有某種意義的詞,比如變量名、常量名、函數(shù)名等等,Go語言中標(biāo)識(shí)符允許由...

    4272021-11-24
  • Golanggolang json.Marshal 特殊html字符被轉(zhuǎn)義的解決方法

    golang json.Marshal 特殊html字符被轉(zhuǎn)義的解決方法

    今天小編就為大家分享一篇golang json.Marshal 特殊html字符被轉(zhuǎn)義的解決方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧 ...

    李浩的life12792020-05-27
  • Golanggolang 通過ssh代理連接mysql的操作

    golang 通過ssh代理連接mysql的操作

    這篇文章主要介紹了golang 通過ssh代理連接mysql的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧...

    a165861639710342021-03-08
  • Golanggo語言制作端口掃描器

    go語言制作端口掃描器

    本文給大家分享的是使用go語言編寫的TCP端口掃描器,可以選擇IP范圍,掃描的端口,以及多線程,有需要的小伙伴可以參考下。 ...

    腳本之家3642020-04-25
  • Golanggolang如何使用struct的tag屬性的詳細(xì)介紹

    golang如何使用struct的tag屬性的詳細(xì)介紹

    這篇文章主要介紹了golang如何使用struct的tag屬性的詳細(xì)介紹,從例子說起,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看...

    Go語言中文網(wǎng)11352020-05-21
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25
主站蜘蛛池模板: 做羞羞视频 | 免费观看又色又爽又黄的崩锅 | 久草在线最新免费 | 免费观看又色又爽又黄的崩锅 | 国产精品一区二区三区在线播放 | 午夜精品网站 | 日本aaa一级片 | 欧美成人免费在线视频 | 国产精品视频一区二区三区四区五区 | av在线免费网址 | 91精品国产91| 国产高清美女一级毛片 | 久久久久se| 成人做爽爽爽爽免费国产软件 | 色日本视频| 国产大片中文字幕在线观看 | 国产成人自拍av | 奇米影视亚洲精品一区 | 午夜视 | 成人免费福利网站 | 欧美成年私人网站 | japanese xxxxhd | 一级毛片在线视频 | 最新视频一区二区 | 久久免费观看一级毛片 | 国产真实孩交 | 国产免费看片 | 久久久久久久久久久av | 亚洲精品久久久久www | 国产精品久久久久国产精品三级 | 久久久电影电视剧免费看 | 国产青草网 | 水卜樱一区二区av | 久久久久久久久久综合 | av在线播放亚洲 | 成人毛片久久 | 日本一区二区视频在线观看 | 久久精品.com | 精品一区二区免费 | 欧美日韩一| 色爽爽爽 |