成人怡红院-成人怡红院视频在线观看-成人影视大全-成人影院203nnxyz-美女毛片在线看-美女免费黄

站長資訊網
最全最豐富的資訊網站

go語言中數組與切片有什么區別

數組與切片的區別:1、切片是指針類型,數組是值類型;2、數組的賦值形式為值傳遞,切片的賦值形式為引用傳遞;3、數組的長度是固定的,而切片長度可以任意調整(切片是動態的數組);4、數組的長度是固定的,而切片長度可以任意調整(切片是動態的數組)。

go語言中數組與切片有什么區別

本教程操作環境:windows7系統、GO 1.18版本、Dell G3電腦。

Go語言中的數組大概相當與C/C++中的數組,固定大小,不能夠動態擴展大小,而切片大概相當與C++中的Vector,可以動態擴展大小,當大小超過容量時,重新分配一塊內存,然后將數據復制到新的內存區域。下面我們通過幾個問題來更好理解golang 的數組和切片,一起來看看吧。

一、數組

Go的切片是在數組之上的抽象數據類型,因此在了解切片之前必須要先理解數組。

1、數組的三種申明方式

  • var identifier [len]type
  • var identifier = [len]type{value1, value2, … , valueN}
  • var identifier = […]type{value1, value2, … , valueN}

相對應的:

  • identifier := [len]type{}
  • identifier := [len]type{value1, value2, … , valueN}
  • identifier := […]type{value1, value2, … , valueN}

例子:

var iarray1 [5]int32 var iarray2 [5]int32 = [5]int32{1, 2, 3, 4, 5} iarray3 := [5]int32{1, 2, 3, 4, 5} iarray4 := [5]int32{6, 7, 8, 9, 10} iarray5 := [...]int32{11, 12, 13, 14, 15} iarray6 := [4][4]int32{{1}, {1, 2}, {1, 2, 3}}    fmt.Println(iarray1) fmt.Println(iarray2) fmt.Println(iarray3) fmt.Println(iarray4) fmt.Println(iarray5) fmt.Println(iarray6)
登錄后復制

結果:

[0 0 0 0 0] [1 2 3 4 5] [1 2 3 4 5] [6 7 8 9 10] [11 12 13 14 15] [[1 0 0 0] [1 2 0 0] [1 2 3 0] [0 0 0 0]]
登錄后復制

我們看數組 iarray1,只聲明,并未賦值,Go語言幫我們自動賦值為0。再看 iarray2 和 iarray3 ,我們可以看到,Go語言的聲明,可以表明類型,也可以不表明類型,var iarray3 = [5]int32{1, 2, 3, 4, 5} 也是完全沒問題的。

2、數組的容量和長度

數組的容量和長度是一樣的。cap() 函數和 len() 函數均輸出數組的容量(即長度)

3、類型

數組是值類型,將一個數組賦值給另一個數組時,傳遞的是一份拷貝。而切片是引用類型,切片包裝的數組稱為該切片的底層數組。看下面的例子:

//a是一個數組,注意數組是一個固定長度的,初始化時候必須要指定長度,不指定長度的話就是切片了 a := [3]int{1, 2, 3} //b是數組,是a的一份拷貝 b := a //c是切片,是引用類型,底層數組是a c := a[:] for i := 0; i < len(a); i++ {  a[i] = a[i] + 1 } //改變a的值后,b是a的拷貝,b不變,c是引用,c的值改變 fmt.Println(a) //[2,3,4] fmt.Println(b) //[1 2 3] fmt.Println(c) //[2,3,4]
登錄后復制

二、切片

Go語言中,切片是長度可變、容量固定的相同的元素序列。Go語言的切片本質是一個數組。容量固定是因為數組的長度是固定的,切片的容量即隱藏數組的長度。長度可變指的是在數組長度的范圍內可變。

1、切片的四種創建方式

  • var slice1 = make([]int,5,10)
  • var slice2 = make([]int,5)
  • var slice3 = []int{}
  • var slice4 = []int{1,2,3,4,5}

相對應的:

  • slice1 := make([]int,5,10)
  • slice2 := make([]int,5)
  • slice3 := []int{}
  • slice4 := []int{1,2,3,4,5}

以上對應的輸出

[0 0 0 0 0] [0 0 0 0 0] [] [1 2 3 4 5]
登錄后復制

從3)、4)可見,創建切片跟創建數組唯一的區別在于 Type 前的“ [] ”中是否有數字,為空,則代表切片,否則則代表數組。因為切片是長度可變的

2、隱藏數組

Go的切片是在數組之上的抽象數據類型,所以創建的切片始終都有一個數組存在。

舉例說明:

slice0 := []string{"a", "b", "c", "d", "e"} slice1 := slice0[2 : len(slice0)-1] slice2 := slice0[:3] fmt.Println(slice0, slice1, slice2) slice2[2] = "8" fmt.Println(slice0, slice1, slice2)
登錄后復制

輸出:

[a b c d e] [c d] [a b c] [a b 8 d e] [8 d] [a b 8]
登錄后復制

也說明,切片slice0 、 slice1 和 slice2是同一個底層數組的引用,所以slice2改變了,其他兩個都會變

3、append追加切片

內置函數append可以向一個切片后追加一個或多個同類型的其他值。如果追加的元素數量超過了原切片容量,那么最后返回的是一個全新數組中的全新切片。如果沒有超過,那么最后返回的是原數組中的全新切片。無論如何,append對原切片無任何影響。

舉例說明:

slice1 := make([]int, 2, 5) fmt.Println(len(slice1), cap(slice1)) for k := range slice1{     fmt.Println(&slice1[k]) } slice1 = append(slice1,4) fmt.Println(len(slice1), cap(slice1)) for k := range slice1{     fmt.Println(&slice1[k]) } slice1 = append(slice1,5,6,7) fmt.Println(len(slice1), cap(slice1)) for k := range slice1{     fmt.Println(&slice1[k]) }
登錄后復制

輸出:

2 5 //長度和容量 0xc420012150 0xc420012158  3 5 //第一次追加,未超出容量,所以內存地址未發生改變 0xc420012150 0xc420012158 0xc420012160  6 10 //第二次追加,超過容量,內存地址都發生了改變,且容量也發生了改變,且是原來的2倍 0xc4200100f0 0xc4200100f8 0xc420010100 0xc420010108 0xc420010110 0xc420010118
登錄后復制

再看一個例子:

slice1 := make([]int, 2, 5) slice2 := slice1[:1] fmt.Println(len(slice1), cap(slice1)) for k := range slice1{     fmt.Println(&slice1[k]) } fmt.Println(len(slice2), cap(slice2)) for k := range slice2{     fmt.Println(&slice2[k]) }  slice2 = append(slice2,4,5,6,7,8)  fmt.Println(len(slice1), cap(slice1)) for k := range slice1{     fmt.Println(&slice1[k]) } fmt.Println(len(slice2), cap(slice2)) for k := range slice2{     fmt.Println(&slice2[k]) }
登錄后復制

以上輸出:

2 5 //slice1的長度和容量 0xc4200700c0 0xc4200700c8  1 5  //slice2的長度和容量 0xc4200700c0  2 5 //slice2追加后,slice1的長度和容量、內存都未發生改變 0xc4200700c0 0xc4200700c8  6 10 //slice2追加后,超過了容量,所以slice2的長度和容量、內存地址都發生改變。 0xc42007e000 0xc42007e008 0xc42007e010 0xc42007e018 0xc42007e020 0xc42007e028
登錄后復制

三、GO中數組與切片的區別

下面的主要看一些實際的例子來說明數組和切片的區別。

1、數組與切片的賦值形式

例子1

arr1 := [3] int {1,2,3} arr2 := arr1 for k := range arr1 {     fmt.Printf("%v ",&arr1[k]); }  fmt.Println("");  for k := range arr2 {     fmt.Printf("%v ",&arr2[k]); }  fmt.Println("n=================");  slice1 := [] int{1,2,3} slice2 := slice1 for k := range slice1 {     fmt.Printf("%v ",&slice1[k]); } fmt.Println(""); for k := range slice2 {     fmt.Printf("%v ",&slice2[k]); }  輸出結果: 0xc420014140 0xc420014148 0xc420014150  0xc420014160 0xc420014168 0xc420014170  ================= 0xc4200141a0 0xc4200141a8 0xc4200141b0  0xc4200141a0 0xc4200141a8 0xc4200141b0
登錄后復制

從這個例子中可以看出,數組的賦值是值的拷貝,是一個全新的數組。而切片的賦值是引用。下面再來看一個例子。

例子2:

arr1 := [3] int {1,2,3} arr2 := arr1 fmt.Printf("%v %v ",arr1,arr2);  arr1[0] = 11 arr2[1] = 22 fmt.Printf("n%v %v ",arr1,arr2);  fmt.Println("n================");  slice1 := [] int{1,2,3} slice2 := slice1 fmt.Printf("%v %v ",slice1,slice2);  slice1[0] = 11 slice2[1] = 22 fmt.Printf("n%v %v ",slice1,slice2);  輸出結果: [1 2 3] [1 2 3]  [11 2 3] [1 22 3]  ================ [1 2 3] [1 2 3]  [11 22 3] [11 22 3]
登錄后復制

這個例子再一次說明:數組是賦值是copy,而切片僅是引用。例子1和例子2中的切片的聲明用到了隱藏數組。再來看下例子3,使用非隱藏數組的情況。

例子3:

arr1 := [5] int {1,2,3} slice1 := arr1[0:3] slice2 := slice1[0:4]  fmt.Printf("len: %d cap: %d %vn",len(arr1),cap(arr1),arr1); //打印出非隱藏數組 for k := range arr1 {     fmt.Printf("%v ",&arr1[k]); }  fmt.Println("");  fmt.Printf("len: %d cap: %d %vn",len(slice1),cap(slice1),slice1); //打印切片1 for k := range slice1 {     fmt.Printf("%v ",&slice1[k]); }  fmt.Println("");  fmt.Printf("len: %d cap: %d %vn",len(slice2),cap(slice2),slice2); //打印切片2 for k := range slice2 {     fmt.Printf("%v ",&slice2[k]); } fmt.Println("n=================");  arr1[0] = 11   //非隱藏數組、切片1、切片2各自發生更改 slice1[1] = 22 slice2[2] = 33  fmt.Printf("len: %d cap: %d %vn",len(arr1),cap(arr1),arr1); //再次打印非隱藏數組 for k := range arr1 {     fmt.Printf("%v ",&arr1[k]); }  fmt.Println("");  fmt.Printf("len: %d cap: %d %vn",len(slice1),cap(slice1),slice1); //再此打印切片1 for k := range slice1 {     fmt.Printf("%v ",&slice1[k]); } fmt.Println("");  fmt.Printf("len: %d cap: %d %vn",len(slice2),cap(slice2),slice2); //再次打印切片2 for k := range slice2 {     fmt.Printf("%v ",&slice2[k]); }  輸出結果: len: 5 cap: 5 [1 2 3 0 0]0xc420012150 0xc420012158 0xc420012160 0xc420012168 0xc420012170  len: 3 cap: 5 [1 2 3]0xc420012150 0xc420012158 0xc420012160 len: 4 cap: 5 [1 2 3 0]0xc420012150 0xc420012158 0xc420012160 0xc420012168  ================= len: 5 cap: 5 [11 22 33 0 0] 0xc420012150 0xc420012158 0xc420012160 0xc420012168 0xc420012170  len: 3 cap: 5 [11 22 33] 0xc420012150 0xc420012158 0xc420012160  len: 4 cap: 5 [11 22 33 0] 0xc420012150 0xc420012158 0xc420012160 0xc42001216
登錄后復制

綜上三個例子,可以看出切片是數組的引用,這里包括對隱藏數組、非隱藏數組引用。

2、數組作為參數,被函數調用

func Connect() {     arr1 := [5] int {1,2,3}     fmt.Printf("%v ",arr1);     for k := range arr1 {         fmt.Printf("%v ",&arr1[k]);     }     fmt.Println("");     f1(arr1)     fmt.Println("");     f2(&arr1) } func f1(arr [5]int) {     fmt.Printf("%v ",arr);     for k := range arr {         fmt.Printf("%v ",&arr[k]);     } } func f2(arr *[5]int) {     fmt.Printf("%v ",arr);     for k := range arr {         fmt.Printf("%v ",&arr[k]);     } }  輸出結果: [1 2 3 0 0]  0xc420012150 0xc420012158 0xc420012160 0xc420012168 0xc420012170  [1 2 3 0 0]  0xc4200121b0 0xc4200121b8 0xc4200121c0 0xc4200121c8 0xc4200121d0  &[1 2 3 0 0] 0xc420012150 0xc420012158 0xc420012160 0xc420012168 0xc420012170
登錄后復制

從上面的例子可以看出,數組在參數中,可以使用值傳遞和引用傳遞。值傳遞會拷貝新數組,引用傳遞則使用原數組。

func Connect() {     slice1 := [] int {1,2,3}     fmt.Printf("%v ",slice1);     for k := range slice1 {         fmt.Printf("%v ",&slice1[k]);     }     fmt.Println("");     f1(slice1) } func f1(slice []int) {     fmt.Printf("%v ",slice);     for k := range slice {         fmt.Printf("%v ",&slice[k]);     } }  輸出結果: [1 2 3] 0xc420014140 0xc420014148 0xc420014150  [1 2 3] 0xc420014140 0xc420014148 0xc42001415
登錄后復制

從這個例子中可以看出,切片在參數中傳遞本身就引用。

總結:

  • 切片是指針類型,數組是值類型

  • 數組的賦值形式為值傳遞,切片的賦值形式為引用傳遞

  • 數組的長度是固定的,而切片長度可以任意調整(切片是動態的數組)

  • 數組只有長度一個屬性,而切片比數組多了一個容量(cap)屬性

贊(0)
分享到: 更多 (0)
?
網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
日本适合十八岁以下的护肤| 欧美性巨大╳╳╳╳╳高跟鞋| 久久一本精品久久精品66| 里番ACG ※里番_ACG工口| 免费免费视频片在线观看| 欧美性战A久久久久久| 色鬼7777久久| 性少妇中国内射XXXX狠干| 亚洲国产婷婷综合在线精品| 张柏芝跪下吃J8图片| JAPANESE失禁潮喷| 国产成人精品123区免费视频| 国产台湾无码AV片在线观看| 久久99精品久久久久久| 女儿的朋友3完有限中字木瓜| 日韩国产女人久久久| 性欧美ⅩXXXX极品少妇| 一二三四免费观看高清在线 | 啪啪无码人妻丰满熟妇| 少妇泬出白浆18P| 亚洲—本道 在线无码AV发 | 老狼老狼芦苇芭蕉| 日本WWW一道久久久免费榴莲| 无码色偷偷亚洲国内自拍| 亚洲欧美日韩中文高清WWW| 最新无码国产在线视频9299| 粉嫩一区二区三区性色AV| 好儿子妈妈今后就是你的人| 免费播放AV网站的地址| 肉身避风港1978大米星球| 亚洲AV无码一区二区高潮| 在线永久无码不卡AV| 动漫成人无码免费视频在线播| 含着她的花蒂啃咬高潮| 免费无码久久成人网站| 天天做天天爱天天爽综合网| 野花高清在线观看免费官网中文版| 锕锕锕锕锕锕~好深啊电影APP | 日韩精品无码观看视频免费| 久久久久国产精品人妻AⅤ蜜臀| 欧美VPSWINDOWS另类| 忘忧草在线影院WWW神马| 夜夜添无码试看一区二区三区| XXXX性×XX老少配| 国产一区二区三区精品视频| 免费网站看AV片| 无码少妇一区二区三区芒果 | 少妇人妻无码永久免费视频| 亚洲人成网站精品片在线观看| YY111111人妻影院| 黄A大片AV永久免费| 人妻人人澡人人添人人爽人人玩 | 久久国内精品自在自线400部 | 久久精品国产亚洲AV网站| 日本肉体裸交ⅩXXXBBBB| 亚洲欧美成人在线观看| 成人午夜爽爽爽免费视频| 精品人妻AV无码一区二区三区| 人妻AV一区二区| 亚洲国产精品久久久久蜜桃噜噜| 爆乳JK美女脱内衣裸体网站| 极品人妻VIDEOSSS人妻| 日韩 无码 偷拍 中文字幕| 亚洲午夜性猛春交XXXX| 公和熄小婷乱中文字幕| 蜜臀av蜜臀一区二区三区| 性做久久久久久久久| 八戒午夜理论片影院| 久久久久成人片免费观看R| 天美传媒MV免费观看| 337P日本欧洲亚洲大胆裸体艺| 国产亚洲美女精品久久久| 人妻少妇aB又紧又爽精品视频 | 精品无码中文字幕不卡| 色噜噜狠狠色综合日日 | 成年美女黄网站色大免费视频| 久久成人国产精品一区二区| 丝袜灬啊灬快灬高潮了AV | 亚洲VA中文字幕无码毛片| 大豆期货交易价格| 男男腐啪GⅤ小受无套进入| 亚洲第一综合天堂另类专| 丰满少妇被粗大猛烈进人高清| 美女内射在线观看| 亚洲AV永久纯肉无码精品动漫 | CHINESE 麻豆 HD X| 久久久久久午夜成人影院| 亚洲AV成人无码精品| 动漫高H纯肉无码视频在线观看| 女儿男朋友是妈妈的爱豆的电视剧 | 久久综合婷婷成人网站| 亚洲AV无码一区二区在线蜜桃| 公主很忙(N)甜烟| 屁屁草草影院CCYYCOM| 尤物精品国产第一福利网站| 好男人HD免费观看| 玩弄丰满少妇XXXXX性多毛| 草莓丝瓜芭乐鸭脖奶茶搭配食物| 妺妺坐在我腿上勃起弄了应用| 亚洲日韩AV一区二区三区中文| 国产午夜免费啪视频观看视频| 日韩在线 | 中文| 99热久RE这里只有精品小草| 久久久久亚洲AV综合波多野结衣 | 用各种刑具调教吹潮的视频 | 国产精品毛片Av无码一区二区| 日韩精品一区二区三区中文| ASS白嫩白嫩的少妇PICS| 鲁鲁夜夜天天综合视频| 亚洲最大的AV网站| 精品久久久无码专区中文字幕| 亚洲AV成人精品五区| 国产精品一区二区久久乐下载 | 国产成人亚洲影院在线播放| 日韩AV无码免费播放| А天堂中文在线官网在线| 欧美成人v片一区二区三区激情| 岳女二人名器共侍一夫的出处| 蜜臀人妻四季AV一区二区不卡| 看全色黄大色黄女片爽在线看| 亚洲AV无码国产精品夜色午夜| 国产猛烈高潮尖叫视频免费| 玩稚嫩的小屁股眼AV| 男女乱婬免费视频黑人| 亚洲国产成人久久精品软件| 国产色欲色欲色欲.WWW| 午夜精品久久久久久| 国产精品久久久久久影视不卡| 偷窥 亚洲 另类 图片 熟女| 国产AV无码专区亚洲AWWW| 少妇短裙公车被直接进入| 高潮潮喷奶水飞溅视频无码| 少妇精品久久久一区二区| 隔着衣服吃你的小尖尖作文| 视频在线一区二区三区| 国产成人AV无码精品| 玩弄JAPAN白嫩少妇HD小说| 国产成人无码A区在线观看导航| 玩丰满少妇ⅩXX性人妖| 国产乱码1卡二卡3卡四卡| 香蕉成人伊视频在线观看| 国产综合AV一区二区三区无码| 亚洲爆乳无码一区二区三区| 精品综合久久久久久8888| 一二三四视频社区3在线高清| 乱VODAFONEWIFI熟妇| 377P欧洲日本亚洲大胆| 人妻丰滿熟妇αV无码HD| 吃了继兄开的药后我做的梦更长了 | 青青青国产成人久久111网站| 把腿张开老子CAO烂你| 日韩视频中文字幕精品偷拍| 国产精品成人嫩草影院| 亚洲AV永久纯肉无码精品wwt| 久久99精品久久久久子伦| 中文字幕乱码人妻综合二区三区| 欧美日韩一区二区三区人妻 | 97久久久精品综合88久久| 人妻无码一区二区三区免费 | 少妇愉情理仑片高潮| 国产一起色一起爱| 夜夜高潮次次欢爽AV女视频| 女人的选择HD中字| 当着老公的面被别人欺负该怎么办| 婷婷精品国产亚洲AV麻豆不片| 狠狠亚洲婷婷综合色香五月加勒比| 亚洲综合色成在线观看| 欧美精品一区二区三区在线| 大胆人体艺术视频| 无人区一码二码三码四码区别在哪| 精品无人码麻豆乱码1区2区| 中文字幕人成无码人妻综合社区| 人妻少妇一区二区三区| 国产精品99久久久久久宅男小说 | 锕锕锕锕锕锕好大好深APP| 偷窥 亚洲 另类 图片 熟女| 精品久久久久久无码中文字幕一区| √新版天堂资源在线资源| 少妇高潮喷潮久久久影院| 狠狠色综合7777久夜色撩人| 中文字幕人乱码中文字幕 | 欧美牲交黑粗硬大在线视频| 国产成人久久综合第一区| 亚洲欧美日韩成人综合网| 欧美日韩一区精品视频一区二区| 国产SP调教打屁股视频网站| 亚洲色18禁成人网站WWW| 情侣过夜的男生会忍住吗| 国产精品久久久久久无遮挡| 夜夜高潮夜夜爽夜夜爱爱一区| 人妻中文乱码在线网站| 国产真人无码作爱免费视频| 竹菊影视欧美日韩一区二区三区四| 色综合久久精品亚洲国产消防| 精品欧洲AV无码一区二区三区 | 又色又爽又黄的视频APP软件下| 日本熟妇人妻XXXXX野外呻| 激情伊人五月天久久综合| YIN荡到骨子里的SAO货| 亚洲H在线播放在线观看H|