<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
陣列是具有相同唯一型別的一組已編號且長度固定的資料項序列,這種型別可以是任意的原始型別例如整型、字串或者自定義型別
var arr [10]int //定義長度為10的型別是int的陣列arr arr[0] = 1 // 陣列的下標從0開始 陣列的賦值 var arr1 = [5]int{1,2,3,4,5} //陣列的初始化的定義方式 arr2 := [5]int{1,2,3,4,5} //同上 arr3 := [...]int{1,2,3,4,5} //編譯器通過元素個數自動推斷陣列的長度
func GetArray(arr [5]int)(v [5]int){ fmt.Printf("GetArray arr===%v, %pn", arr,&arr) // 檢視傳進來的引數和地址 arr[1] = 3 //修改其中的一個值 return arr } func main(){ arr :=[...]int{1,2,3,4,5} // 定義一個長度為5 型別是int的陣列 fmt.Printf("main arr=%v, %pn", arr, &arr) value := GetArray(arr) fmt.Printf("main GetArray value=%v, %p, arr=%v,%pn", value, &value,arr, &arr) }
輸出結果:
main arr=[1 2 3 4 5], 0xc000012390
GetArray arr===[1 2 3 4 5], 0xc000012420
main GetArray value=[1 3 3 4 5], 0xc0000123f0, arr=[1 2 3 4 5],0xc000012390
從上面的輸出結果來看 當使用陣列作為引數和返回值的時候,傳進去的是值,在函數內部對陣列進行修改並不會影響原資料
Go 語言切片是對陣列的抽象。
Go 陣列的長度不可改變,在特定場景中這樣的集合就不太適用,Go 中提供了一種靈活,功能強悍的內建型別切片(“動態陣列”),與陣列相比切片的長度是不固定的,可以追加元素,在追加時可能使切片的容量增大。
var myslice []int //定義一個切片 所有的資料型別都是int 切片與陣列的定義差別是可以不帶長度 var myslice []int = make([]int ,5) //定義一個長度為5的切片 myslice1 := make([]int,5) //同上 make([]T, length, capacity) //定義的引數分別是型別,長度,容量(可選) myslice2 :=[] int {1,2,3 } //切片初始化 myarr := [...]int{1,2,3,4,5} myslice3 := myarr[1:3] //也可以先定義一個陣列 然後擷取這裡是從下標1開始到下標為3(不包含)
ps:當我們通過從陣列擷取獲得切片的時候,我們可以發現擷取後的切片和原來的陣列是共用資料來源的,如果修改原來的陣列資料來源 那麼通過擷取陣列得到的切片的值也會被修改反之亦然
func main(){ arr :=[...]int{1,2,3,4,5} // 定義一個長度為5 型別是int的陣列 myslice1 := arr[0:3] //切片獲取下標[0,3)的值 myslice2 := arr[0:4] //切片獲取下標[1,4)的值 fmt.Printf("myslice1=%v, ppp=%pn", myslice1, &myslice1) fmt.Printf("myslice2=%v, ppp=%pn", myslice2, &myslice2) arr[1] = 666 //修改陣列的值 fmt.Printf("After myslice1=%v, ppp=%pn", myslice1, &myslice1) fmt.Printf("After myslice2=%v, ppp=%pn", myslice2, &myslice2) myslice2[2] =777 //修改切片的值 fmt.Printf("arr=%v", arr) }
輸出的結果:
myslice1=[1 2 3], ppp=0xc000004078
myslice2=[1 2 3 4], ppp=0xc000004090
After myslice1=[1 666 3], ppp=0xc000004078
After myslice2=[1 666 3 4], ppp=0xc000004090
arr=[1 666 777 4 5]
一部分是存的指向匿名陣列的指標,一個是長度,一個是容量,我們在定義切片的時候 會在底層儲存一個匿名的陣列,通過上面的陣列得到切片的方式得出的結論 當我們通過一個切片得到另一個切片的時候我們的資料來源也是共用的
func GetSlice(myslice []int)(value []int){ fmt.Printf("GetSlice myslice===%v, ppppp=%pn", myslice,&myslice) // 檢視傳進來的引數和地址 myslice[2] = 10 return myslice } func main(){ var myslice []int //定義一個空的切片 myslice = append(myslice, 1) myslice = append(myslice, 2) myslice = append(myslice, 3) myslice = append(myslice, 4) myslice = append(myslice, 5) //向切片裡面追加元素 fmt.Printf("myslice ==%v ppp=%pn", myslice, &myslice) rslice := GetSlice(myslice) fmt.Printf("rslice==%v ppp=%p, myslice==%v,ppp=%pn", rslice,&rslice,myslice,&myslice) }
輸出結果:
myslice ==[1 2 3 4 5] ppp=0xc000004078
GetSlice myslice===[1 2 3 4 5], ppppp=0xc0000040c0
rslice==[1 2 10 4 5] ppp=0xc0000040a8, myslice==[1 2 10 4 5],ppp=0xc000004078
結論:從上面的輸出的結果和地址來看,當切片作為引數的時候穿進去的是值,也就是值傳遞,但是當我在函數裡面修改切片的時候,我們發現源資料也會被修改,這是因為我們在切片的底層維護這一個匿名的陣列,當我們把切片當成引數的時候,會重現建立一個切片,但是建立的這個切片和我們原來的資料是共用資料來源的,所以在函數內被修改,源資料也會被修改
golang提供了append 函數向切片中增加元素,但是切片和陣列一樣也是有長度的,如果新增的元素個數剛好在長度範圍內,就直接在末尾新增元素,但是如果新增的元素的個數超過了長度之後,就需要對底層的陣列進行擴容了,這個新的陣列的長度是原來的兩倍 ,而建立這個新的陣列之後我們將新的陣列的指標儲存到切片資料中,就這樣我們實現了切片的動態增長,而當切片作為引數的時候,如果我們在函數裡使用append函數增加元素,且元素的個數超過長度的話 在函數中我們就會建立除一個新的切片這個時候我們在函數內對新的切片進行修改 就不會影響到原來的切片了
func GetSlice(myslice []int)(value []int){ fmt.Printf("GetSlice myslice===%v, ppppp=%pn", myslice,&myslice) // 檢視傳進來的引數和地址 myslice = append(myslice, 6) return myslice } func main(){ myslice := make([]int,5) //定義長度為5 型別是int的切片 for i:=0; i< len(myslice);i++{ myslice[i] = i+1 } fmt.Printf("myslice ==%v ppp=%pn", myslice, &myslice) rslice := GetSlice(myslice) fmt.Printf("rslice==%v ppp=%p, myslice==%v,ppp=%pn", rslice,&rslice,myslice,&myslice) }
輸出結果:
myslice ==[1 2 3 4 5] ppp=0xc000004078
GetSlice myslice===[1 2 3 4 5], ppppp=0xc0000040c0
rslice==[1 2 3 4 5 6] ppp=0xc0000040a8, myslice==[1 2 3 4 5],ppp=0xc000004078
func main(){ myslice := make([]int,5) //定義長度為5 型別是int的切片 for i:=0; i< len(myslice);i++{ myslice[i] = i+1 } fmt.Printf("myslice ==%v ppp=%pn", myslice, &myslice) copymyslice := make([]int,5) copy(copymyslice, myslice) myslice[4] = 10 fmt.Printf("copymyslice ==%v myslice=%vn", copymyslice, myslice) }
輸出結果:
myslice ==[1 2 3 4 5] ppp=0xc000004078
copymyslice ==[1 2 3 4 5] myslice=[1 2 3 4 10]
結論:使用copy函數對切片進行賦值的時候可以避免源資料與目標資料共用底層陣列
陣列還是切片,在函數中傳遞的時候如果沒有指定為指標傳遞的話,都是值傳遞,但是切片在傳遞的過程中,有著共用底層陣列的風險,所以如果在函數內部進行了更改的時候,會修改到源資料,所以我們需要根據不同的需求來處理,如果我們不希望源資料被修改話的我們可以使用copy函數複製切片後再傳入,如果希望源資料被修改的話我們應該使用指標傳遞的方式
到此這篇關於golang陣列和切片作為引數和返回值的實現的文章就介紹到這了,更多相關golang陣列和切片作為引數和返回值內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45