真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

go語言list和切片,go 定義切片

go和python切片的不同

go有切片slice類型,python有列表和元組,這兩種語言都有切片操作。

成都創(chuàng)新互聯(lián)專注于尉氏企業(yè)網(wǎng)站建設(shè),響應(yīng)式網(wǎng)站建設(shè),成都商城網(wǎng)站開發(fā)。尉氏網(wǎng)站建設(shè)公司,為尉氏等地區(qū)提供建站服務(wù)。全流程按需規(guī)劃網(wǎng)站,專業(yè)設(shè)計(jì),全程項(xiàng)目跟蹤,成都創(chuàng)新互聯(lián)專業(yè)和態(tài)度為您提供的服務(wù)

但是它們的切片操作是完全不同的。

首先說第一個,go的切片,其成員是相同類型的,python的列表和元組則不限制類型。

兩種語言都有[a:b]這種切片操作,意義也類似,但是go的a、b兩個參數(shù)不能是負(fù)數(shù),python可以是負(fù)數(shù),此時就相當(dāng)于從末尾往前數(shù)。

兩種語言都有[a:b:c]這種切片操作,意義卻是完全不同的。go的c,表示的是容量;而python的c表示的是步長。

但是最大的不同,還是:

python的切片產(chǎn)生的是新的對象,對新對象的成員的操作不影響舊對象;go的切片產(chǎn)生的是舊對象一部分的引用,對其成員的操作會影響舊對象。

究其原因,還是底層實(shí)現(xiàn)的不同。

go的切片,底層是一個三元組,一個指針,一個長度,一個容量。指針指向一塊連續(xù)的內(nèi)存,長度是已有成員數(shù),容量是最大成員數(shù)。切片時,一般并不會申請新的內(nèi)存,而是對原指針進(jìn)行移動,然后和新的長度、容量組成一個切片類型值返回。也就是說,go的切片操作通常會和生成該切片的切片共用內(nèi)存。

不僅是切片,字符串、數(shù)組的切片也是一樣的,通常會共用內(nèi)存。

當(dāng)然也有異常情況,那就是切片時,提供的容量過大,此時會申請新內(nèi)存并拷貝;或者對切片append超出容量,也會如此。這時,新的切片,才不會和老切片共享內(nèi)存。(如果你切片/創(chuàng)建時提供的容量小于長度,會panic)

python的列表,其實(shí)是個指針數(shù)組。當(dāng)然在下層也會提供一些空位之類的,但基本就是個數(shù)組。對它們切片,會創(chuàng)建新的數(shù)組,注意,是創(chuàng)建新的數(shù)組!python的列表可沒有容量的概念。

這其實(shí)也體現(xiàn)了腳本語言和編譯語言的不同。雖然兩個語言都有類似的切片操作;但是python主要目標(biāo)是方便;go主要目標(biāo)卻是快速(并彌補(bǔ)丟棄指針運(yùn)算的缺陷)。 a

GO 語言 切片和底層數(shù)組的關(guān)系

//從數(shù)組中獲取 切片

span style="color:#c0c0c0;" /spanspan style="color:#000080;font-weight:600;"var/spanspan style="color:#c0c0c0;" /spansliceArrayspan style="color:#c0c0c0;" /spanspan style="color:#000000;"[/spanspan style="color:#800080;"10/spanspan style="color:#000000;"]/spanspan style="color:#000080;"int/spanspan style="color:#c0c0c0;" /spanspan style="color:#000000;"=/spanspan style="color:#c0c0c0;" /spanspan style="color:#000000;"[/spanspan style="color:#800080;"10/spanspan style="color:#000000;"]/spanspan style="color:#000080;"int/spanspan style="color:#000000;"{/spanspan style="color:#800080;"0/spanspan style="color:#000000;",/spanspan style="color:#c0c0c0;" /spanspan style="color:#800080;"1/spanspan style="color:#000000;",/spanspan style="color:#c0c0c0;" /spanspan style="color:#800080;"2/spanspan style="color:#000000;",/spanspan style="color:#c0c0c0;" /spanspan style="color:#800080;"3/spanspan style="color:#000000;",/spanspan style="color:#c0c0c0;" /spanspan style="color:#800080;"4/spanspan style="color:#000000;",/spanspan style="color:#c0c0c0;" /spanspan style="color:#800080;"5/spanspan style="color:#000000;",/spanspan style="color:#c0c0c0;" /spanspan style="color:#800080;"6/spanspan style="color:#000000;",/spanspan style="color:#c0c0c0;" /spanspan style="color:#800080;"7/spanspan style="color:#000000;",/spanspan style="color:#c0c0c0;" /spanspan style="color:#800080;"8/spanspan style="color:#000000;",/spanspan style="color:#c0c0c0;" /spanspan style="color:#800080;"9/spanspan style="color:#000000;"}/span

//指定 begin index 和end Index

// begin index 和end index 都指定的情況 包括 begin index, 不包括end index index 從0開始

var slice2 []int = sliceArray[5:9]

// slice3 和slice2 指向同一個底層的數(shù)組

var slice3 []int = sliceArray[:]

//輸出結(jié)果 [5 6 7 8] 4 5

fmt.Println(slice2, len(slice2), cap(slice2))

//測試添加元素 and 擴(kuò)容之后的數(shù)組操作情況

//通過切片直接操作數(shù)組的信息

slice2[0] = 100

sliceArray[6] = 66

//多個切片 操作底層數(shù)組

slice3[7] = 77

//輸出結(jié)果 [100 66 77 8] 4 5 三個賦值 都影響了切片的底層數(shù)組

fmt.Println(slice2, len(slice2), cap(slice2))

//輸出結(jié)果 [0 1 2 3 4 100 66 77 8 9] 10 10

fmt.Println(slice3, len(slice3), cap(slice3))

//輸出結(jié)果 [0 1 2 3 4 100 66 77 8 9] 三個賦值 都影響了 原始數(shù)組

fmt.Println("sliceArray:", sliceArray)

//擴(kuò)容

// 操作的還是 sliceArray

slice2 = append(slice2, 99)

//輸出結(jié)果 [100 66 77 8 99] 5 5

fmt.Println(slice2, len(slice2), cap(slice2))

// 輸出結(jié)果 sliceArray: [0 1 2 3 4 100 66 77 8 99]

fmt.Println("sliceArray:", sliceArray)

slice2 = append(slice2, 1000)

//輸出結(jié)果 [100 66 77 8 99 1000] 6 10 此處切片已經(jīng)擴(kuò)容(兩倍擴(kuò)容), 并保留了原始的內(nèi)容

fmt.Println(slice2, len(slice2), cap(slice2))

// 輸出結(jié)果 sliceArray: [0 1 2 3 4 100 66 77 8 99] 原來的數(shù)組不再受到影響了

fmt.Println("sliceArray:", sliceArray)

//通過index操作 元素 判斷擴(kuò)容后的底層數(shù)組是否是部分會在原始的 數(shù)組上面

slice2[1] = 999

//輸出結(jié)果 [100 999 77 8 99 1000] 6 10

fmt.Println(slice2, len(slice2), cap(slice2))

// 輸出結(jié)果 sliceArray: [0 1 2 3 4 100 66 77 8 99] 說明是 重新找了一塊內(nèi)存, 和以前的數(shù)組完全沒有關(guān)系

fmt.Println("sliceArray:", sliceArray)

go的數(shù)組和切片初始化

數(shù)組

數(shù)組是內(nèi)置(build-in)類型,是一組同類型數(shù)據(jù)的集合。

數(shù)組的初始化有多種形式

長度為5的數(shù)組,其元素值依次為:1,2,3,4,5

長度為5的數(shù)組,其元素值依次為:1,2,0,0,0 。在初始化時沒有指定初值的元素將會賦值為其元素類型int的默認(rèn)值0,string的默認(rèn)值是 ""

長度為5的數(shù)組,其長度是根據(jù)初始化時指定的元素個數(shù)決定的

長度為5的數(shù)組,key:value,其元素值依次為:0,0,1,2,3。在初始化時指定了2,3,4索引中對應(yīng)的值:1,2,3

長度為5的數(shù)組,起元素值依次為:0,0,1,0,3。由于指定了最大索引4對應(yīng)的值3,根據(jù)初始化的元素個數(shù)確定其長度為5

切片

數(shù)組的長度不可改變,在特定場景中這樣的集合就不太適用,Go中提供了一種靈活,功能強(qiáng)悍的內(nèi)置類型 Slices 切片。

切片可以通過數(shù)組來初始化,也可以通過內(nèi)置函數(shù)make()初始化。初始化時len=cap,在追加元素時如果容量cap不足時將按len的 2 倍擴(kuò)容。

直接初始化切片, [] 表示是切片類型, {1,2,3} 初始化值依次是1,2,3.其cap=len=3

初始化切片s,是數(shù)組arr的引用

將arr中從下標(biāo)startIndex到endIndex-1 下的元素 創(chuàng)建為一個新的切片

缺省endIndex時將表示一直到arr的最后一個元素

缺省startIndex時將表示從arr的第一個元素開始

通過切片s初始化切片s1

通過內(nèi)置函數(shù)make()初始化切片s,[]int 標(biāo)識為其元素類型為int的切片

golang變量(二)——map和slice詳解

衍生類型,interface{} , map, [] ,struct等

map類似于java的hashmap,python的dict,php的hash array。

常規(guī)的for循環(huán),可以用for k,v :=range m {}. 但在下面清空有一個坑注意:

著名的map[string]*struct 副本問題

結(jié)果:

Go 中不存在引用傳遞,所有的參數(shù)傳遞都是值傳遞,而map是等同于指針類型的,所以在把map變量傳遞給函數(shù)時,函數(shù)對map的修改,也會實(shí)質(zhì)改變map的值。

slice類似于其他語言的數(shù)組(list,array),slice初始化和map一樣,這里不在重復(fù)

除了Pointer數(shù)組外,len表示使用長度,cap是總?cè)萘浚琺ake([]int, len, cap)可以預(yù)申請 比較大的容量,這樣可以減少容量拓展的消耗,前提是要用到。

cap是計(jì)算切片容量,len是計(jì)算變量長度的,兩者不一樣。具體例子如下:

結(jié)果:

分析:cap是計(jì)算當(dāng)前slice已分配的容量大小,采用的是預(yù)分配的伙伴算法(當(dāng)容量滿時,拓展分配一倍的容量)。

append是slice非常常用的函數(shù),用于添加數(shù)據(jù)到slice中,但如果使用不好,會有下面的問題:

預(yù)期是[1 2 3 4 5 6 7 8 9 10], [1 2 3 4 5 6 7 8 9 10 11 12],但實(shí)際結(jié)果是:

注意slice是值傳遞,修改一下:

輸出如下:

== 只能用于判斷常規(guī)數(shù)據(jù)類型,無法使用用于slice和map判斷,用于判斷map和slice可以使用reflect.DeepEqual,這個函數(shù)用了遞歸來判斷每層的k,v是否一致。

當(dāng)然還有其他方式,比如轉(zhuǎn)換成json,但小心有一些異常的bug,比如html編碼,具體這個json問題,待后面在分析。

Golang 中數(shù)組(Array)和切片(Slice)的區(qū)別

Go 中數(shù)組的長度是不可改變的,而 Slice 解決的就是對不定長數(shù)組的需求。他們的區(qū)別主要有兩點(diǎn)。

數(shù)組:

切片:

注意 1

雖然數(shù)組在初始化時也可以不指定長度,但 Go 語言會根據(jù)數(shù)組中元素個數(shù)自動設(shè)置數(shù)組長度,并且不可改變。切片通過 append 方法增加元素:

如果將 append 用在數(shù)組上,你將會收到報(bào)錯:first argument to append must be slice。

注意 2

切片不只有長度(len)的概念,同時還有容量(cap)的概念。因此切片其實(shí)還有一個指定長度和容量的初始化方式:

這就初始化了一個長度為3,容量為5的切片。

此外,切片還可以從一個數(shù)組中初始化(可應(yīng)用于如何將數(shù)組轉(zhuǎn)換成切片):

上述例子通過數(shù)組 a 初始化了一個切片 s。

當(dāng)切片和數(shù)組作為參數(shù)在函數(shù)(func)中傳遞時,數(shù)組傳遞的是值,而切片傳遞的是指針。因此當(dāng)傳入的切片在函數(shù)中被改變時,函數(shù)外的切片也會同時改變。相同的情況,函數(shù)外的數(shù)組則不會發(fā)生任何變化。

go語言中實(shí)現(xiàn)切片(slice)的三種方式

定義一個切片,然后讓切片去引用一個已經(jīng)創(chuàng)建好的數(shù)組?;菊Z法如下:

索引1:切片引用的起始元素位

索引2:切片只引用該元素位之前的元素

例程如下:

在該方法中,我們未指定容量cap,這里的值為5是系統(tǒng)定義的。

在方法一中,可以用arr數(shù)組名來操控?cái)?shù)組中的元素,也可以通過slice切片來操控?cái)?shù)組中的元素。切片是直接引用數(shù)組,數(shù)組是事先存在的,程序員是可見的。

通過 make 來創(chuàng)建切片,基本語法如下:

make函數(shù)第三個參數(shù)cap即容量是可選的,如果一定要自己注明的話,要注意保證cap≥len。

用該方法可以 指定切片的大小(len)和容量(cap)

例程如下:

由于未賦值系統(tǒng)默認(rèn)將元素值置為0,即:

數(shù)值類型數(shù)組:????默認(rèn)值為 0

字符串?dāng)?shù)組:? ? ? ?默認(rèn)值為 ""

bool數(shù)組:? ? ? ? ? ?默認(rèn)值為 false

在方法二中,通過make方式創(chuàng)建的切片對應(yīng)的數(shù)組是由make底層維護(hù),對外不可見,即只能通過slice去訪問各個元素。

定義一個切片,直接就指定具體數(shù)組,使用原理類似于make的方式。

例程如下:


網(wǎng)站名稱:go語言list和切片,go 定義切片
文章源于:http://weahome.cn/article/dscpiog.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部