欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

golang數(shù)組和切片作為參數(shù)和返回值的實現(xiàn)

 更新時間:2022年02月09日 09:58:55   作者:weixin_44387482  
本文主要介紹了golang數(shù)組和切片作為參數(shù)和返回值的實現(xiàn),文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

1. 數(shù)組作為參數(shù)和返回值時

1.1數(shù)組的定義

數(shù)組是具有相同唯一類型的一組已編號且長度固定的數(shù)據(jù)項序列,這種類型可以是任意的原始類型例如整型、字符串或者自定義類型

var arr [10]int  //定義長度為10的類型是int的數(shù)組arr
arr[0] = 1   // 數(shù)組的下標從0開始 數(shù)組的賦值
var arr1 = [5]int{1,2,3,4,5}  //數(shù)組的初始化的定義方式
arr2 := [5]int{1,2,3,4,5} //同上
arr3 := [...]int{1,2,3,4,5} //編譯器通過元素個數(shù)自動推斷數(shù)組的長度

1.2數(shù)組作為參數(shù)和返回值的時候

func GetArray(arr [5]int)(v [5]int){
?? ?fmt.Printf("GetArray arr===%v, %p\n", arr,&arr) // 查看傳進來的參數(shù)和地址
?? ?arr[1] = 3 //修改其中的一個值
?? ?return arr
}

func main(){
?? ?arr :=[...]int{1,2,3,4,5} ?// 定義一個長度為5 類型是int的數(shù)組
?? ?fmt.Printf("main arr=%v, %p\n", arr, &arr)
?? ?value := GetArray(arr)
?? ?fmt.Printf("main GetArray value=%v, %p, arr=%v,%p\n", value, &value,arr, &arr)
}

輸出結(jié)果:
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

從上面的輸出結(jié)果來看 當使用數(shù)組作為參數(shù)和返回值的時候,傳進去的是值,在函數(shù)內(nèi)部對數(shù)組進行修改并不會影響原數(shù)據(jù)

2.切片作為參數(shù)和返回值

2.1 切片的定義初始化

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

var myslice []int ?//定義一個切片 所有的數(shù)據(jù)類型都是int 切片與數(shù)組的定義差別是可以不帶長度
var myslice []int = make([]int ,5) //定義一個長度為5的切片?
myslice1 := make([]int,5) //同上?
make([]T, length, capacity) //定義的參數(shù)分別是類型,長度,容量(可選)
myslice2 :=[] int {1,2,3 } ? //切片初始化
myarr := [...]int{1,2,3,4,5}?
myslice3 := myarr[1:3] //也可以先定義一個數(shù)組 然后截取這里是從下標1開始到下標為3(不包含)

ps:當我們通過從數(shù)組截取獲得切片的時候,我們可以發(fā)現(xiàn)截取后的切片和原來的數(shù)組是共用數(shù)據(jù)源的,如果修改原來的數(shù)組數(shù)據(jù)源 那么通過截取數(shù)組得到的切片的值也會被修改反之亦然

func main(){
?? ?arr :=[...]int{1,2,3,4,5} ?// 定義一個長度為5 類型是int的數(shù)組
?? ?myslice1 := arr[0:3] //切片獲取下標[0,3)的值
?? ?myslice2 := arr[0:4] //切片獲取下標[1,4)的值
?? ?fmt.Printf("myslice1=%v, ppp=%p\n", myslice1, &myslice1)
?? ?fmt.Printf("myslice2=%v, ppp=%p\n", myslice2, &myslice2)
?? ?arr[1] = 666 //修改數(shù)組的值
?? ?fmt.Printf("After myslice1=%v, ppp=%p\n", myslice1, &myslice1)
?? ?fmt.Printf("After myslice2=%v, ppp=%p\n", myslice2, &myslice2)
?? ?myslice2[2] =777 //修改切片的值
?? ?fmt.Printf("arr=%v", arr)
}

輸出的結(jié)果:
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]

2.2 切片的存儲大致分為3部分

一部分是存的指向匿名數(shù)組的指針,一個是長度,一個是容量,我們在定義切片的時候 會在底層保存一個匿名的數(shù)組,通過上面的數(shù)組得到切片的方式得出的結(jié)論 當我們通過一個切片得到另一個切片的時候我們的數(shù)據(jù)源也是共享的

2.3 切片作為參數(shù)和返回值

func GetSlice(myslice []int)(value []int){
?? ?fmt.Printf("GetSlice myslice===%v, ppppp=%p\n", myslice,&myslice) // 查看傳進來的參數(shù)和地址
?? ?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=%p\n", myslice, &myslice)
?? ?rslice := GetSlice(myslice)
?? ?fmt.Printf("rslice==%v ppp=%p, myslice==%v,ppp=%p\n", rslice,&rslice,myslice,&myslice)
}

輸出結(jié)果:
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

結(jié)論:從上面的輸出的結(jié)果和地址來看,當切片作為參數(shù)的時候穿進去的是值,也就是值傳遞,但是當我在函數(shù)里面修改切片的時候,我們發(fā)現(xiàn)源數(shù)據(jù)也會被修改,這是因為我們在切片的底層維護這一個匿名的數(shù)組,當我們把切片當成參數(shù)的時候,會重現(xiàn)創(chuàng)建一個切片,但是創(chuàng)建的這個切片和我們原來的數(shù)據(jù)是共享數(shù)據(jù)源的,所以在函數(shù)內(nèi)被修改,源數(shù)據(jù)也會被修改

2.4 append 切片動態(tài)增長的原理

golang提供了append 函數(shù)向切片中增加元素,但是切片和數(shù)組一樣也是有長度的,如果添加的元素個數(shù)剛好在長度范圍內(nèi),就直接在末尾添加元素,但是如果添加的元素的個數(shù)超過了長度之后,就需要對底層的數(shù)組進行擴容了,這個新的數(shù)組的長度是原來的兩倍 ,而創(chuàng)建這個新的數(shù)組之后我們將新的數(shù)組的指針保存到切片數(shù)據(jù)中,就這樣我們實現(xiàn)了切片的動態(tài)增長,而當切片作為參數(shù)的時候,如果我們在函數(shù)里使用append函數(shù)增加元素,且元素的個數(shù)超過長度的話 在函數(shù)中我們就會創(chuàng)建除一個新的切片這個時候我們在函數(shù)內(nèi)對新的切片進行修改 就不會影響到原來的切片了

func GetSlice(myslice []int)(value []int){
?? ?fmt.Printf("GetSlice myslice===%v, ppppp=%p\n", myslice,&myslice) // 查看傳進來的參數(shù)和地址
?? ?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=%p\n", myslice, &myslice)
?? ?rslice := GetSlice(myslice)
?? ?fmt.Printf("rslice==%v ppp=%p, myslice==%v,ppp=%p\n", rslice,&rslice,myslice,&myslice)
}

輸出結(jié)果:
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

2.5 copy 函數(shù) 通過賦值切片可以使得兩個切片的數(shù)據(jù)不共享

func main(){
?? ?myslice := make([]int,5) ?//定義長度為5 類型是int的切片
?? ?for i:=0; i< len(myslice);i++{
?? ??? ?myslice[i] = i+1
?? ?}
?? ?fmt.Printf("myslice ==%v ppp=%p\n", myslice, &myslice)
?? ?copymyslice := make([]int,5)
?? ?copy(copymyslice, myslice)
?? ?myslice[4] = 10
?? ?fmt.Printf("copymyslice ==%v myslice=%v\n", copymyslice, myslice)
}

輸出結(jié)果:
myslice ==[1 2 3 4 5] ppp=0xc000004078
copymyslice ==[1 2 3 4 5] myslice=[1 2 3 4 10]

結(jié)論:使用copy函數(shù)對切片進行賦值的時候可以避免源數(shù)據(jù)與目標數(shù)據(jù)共享底層數(shù)組

3. 總結(jié):

數(shù)組還是切片,在函數(shù)中傳遞的時候如果沒有指定為指針傳遞的話,都是值傳遞,但是切片在傳遞的過程中,有著共享底層數(shù)組的風(fēng)險,所以如果在函數(shù)內(nèi)部進行了更改的時候,會修改到源數(shù)據(jù),所以我們需要根據(jù)不同的需求來處理,如果我們不希望源數(shù)據(jù)被修改話的我們可以使用copy函數(shù)復(fù)制切片后再傳入,如果希望源數(shù)據(jù)被修改的話我們應(yīng)該使用指針傳遞的方式

到此這篇關(guān)于golang數(shù)組和切片作為參數(shù)和返回值的實現(xiàn)的文章就介紹到這了,更多相關(guān)golang數(shù)組和切片作為參數(shù)和返回值內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Go語言中日志統(tǒng)一處理詳解

    Go語言中日志統(tǒng)一處理詳解

    在現(xiàn)代軟件開發(fā)中,日志記錄是一項至關(guān)重要的任務(wù),它不僅幫助開發(fā)人員診斷問題,還有助于監(jiān)控和維護應(yīng)用程序,本文主要來和大家聊聊日志的統(tǒng)一處理,感興趣的小伙伴可以了解下
    2024-01-01
  • golang中判斷請求是http還是https獲取當前訪問地址

    golang中判斷請求是http還是https獲取當前訪問地址

    這篇文章主要為大家介紹了golang中判斷請求是http還是https獲取當前訪問地址示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-10-10
  • go benchmark 基準測試詳解

    go benchmark 基準測試詳解

    這篇文章主要介紹了go benchmark 基準測試詳解,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-03-03
  • Go-客戶信息關(guān)系系統(tǒng)的實現(xiàn)

    Go-客戶信息關(guān)系系統(tǒng)的實現(xiàn)

    這篇文章主要介紹了Go-客戶信息關(guān)系系統(tǒng)的實現(xiàn),本文章內(nèi)容詳細,具有很好的參考價值,希望對大家有所幫助,需要的朋友可以參考下
    2023-01-01
  • 詳解Golang實現(xiàn)http重定向https的方式

    詳解Golang實現(xiàn)http重定向https的方式

    這篇文章主要介紹了詳解Golang實現(xiàn)http重定向https的方式,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-08-08
  • 一文詳解golang延時任務(wù)的實現(xiàn)

    一文詳解golang延時任務(wù)的實現(xiàn)

    這篇文章主要為大家介紹了golang延時任務(wù)的實現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-03-03
  • Go語言基礎(chǔ)學(xué)習(xí)之指針詳解

    Go語言基礎(chǔ)學(xué)習(xí)之指針詳解

    Go 語言中指針是很容易學(xué)習(xí)的,Go 語言中使用指針可以更簡單的執(zhí)行一些任務(wù)。所以本文就來和大家聊聊Go語言中指針的定義與使用,需要的可以參考一下
    2022-12-12
  • GO文件創(chuàng)建及讀寫操作示例詳解

    GO文件創(chuàng)建及讀寫操作示例詳解

    這篇文章主要為大家介紹了GO文件創(chuàng)建及讀寫操作示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步早日升職加薪
    2022-04-04
  • 詳解Golang中字符串的使用

    詳解Golang中字符串的使用

    這篇文章主要為大家詳細介紹了Golang中字符串的使用,文中的示例代碼講解詳細,對我們學(xué)習(xí)Golang有一定的幫助,感興趣的小伙伴可以了解一下
    2022-10-10
  • GO語言實現(xiàn)標題閃爍效果

    GO語言實現(xiàn)標題閃爍效果

    這篇文章主要介紹了GO語言實現(xiàn)標題閃爍效果,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-07-07

最新評論