<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          一篇文章帶你了解Go語言基礎(chǔ)之切片補(bǔ)充

          共 2995字,需瀏覽 6分鐘

           ·

          2022-04-28 23:16

          點擊上方“Go語言進(jìn)階學(xué)習(xí)”,進(jìn)行關(guān)注

          回復(fù)“Go語言”即可獲贈Python從入門到進(jìn)階共10本電子書

          錦城雖云樂,不如早還家。

          ????上篇文章中我們學(xué)習(xí)了Go語言基礎(chǔ)中的變量,一篇文章帶你了解Go語言基礎(chǔ)之變量,這篇文章我們繼續(xù)介紹Go語言基礎(chǔ)知識,今天跟大家分享的是基礎(chǔ)數(shù)據(jù)類型之切片補(bǔ)充,一起來學(xué)習(xí)下吧~


          前言

          Hey,大家好呀,我是星期八,這次咱們繼續(xù)學(xué)習(xí)Go基礎(chǔ)之切片補(bǔ)充扒。


          make疑云

          我們知道,可以通過make創(chuàng)建切片。

          var names = make([]string1010)

          這句話表示動態(tài)創(chuàng)建了一個切片,切片中的元素數(shù)量為10個,切片的容量也為10個。

          你有疑惑嗎???

          切片的數(shù)量和容量是什么???

          他倆什么關(guān)系???


          切片本質(zhì)

          其實切片,終究是一個存儲數(shù)據(jù)的一個東西,目前知道數(shù)組是可以存儲東西的。

          其實切片本質(zhì),還是數(shù)組,只不過是Go幫助我們做了一些封裝,可以方便的對切片里面的數(shù)據(jù)增刪改查

          例如:

          package main
          import "fmt"
          func main() { var names = make([]int410) //int類型默認(rèn)值是0 fmt.Println(names, len(names), cap(names)) //結(jié)果:[0 0 0 0] 4 10}

          理解圖。

          沒錯,本質(zhì)就是指向了一個長一點的數(shù)組。

          但是這個數(shù)組是會自動擴(kuò)容的,當(dāng)容量(cap)append滿了之后,會自動擴(kuò)容。

          現(xiàn)在,我們就知道m(xù)ake里面參數(shù)的意義了。

          注意:在Go中,推薦使用make創(chuàng)建切片,并且在創(chuàng)建時,需要考慮容量,盡可能不觸發(fā)容量自動擴(kuò)容機(jī)制,提高性能。


          為什么切片append之后,前面會有空格

          在上一章中,大概有這樣一段代碼。

          package main
          import "fmt"
          func main() { var names = make([]int510) names = append(names,1123231) fmt.Println(names)//[0 0 0 0 0 11 23 231]}

          append之后,前面會有很多0,這是怎么回事。

          解釋:

          在通過make創(chuàng)建切片時,第二個參數(shù)切片元素數(shù)量

          上述代碼切片第二個參數(shù)是5,表示在創(chuàng)建切片時,前5個就已經(jīng)有值了,只不過是int默認(rèn)值0。

          所以再append時,是再原有的基礎(chǔ)上,添加值的,直到cap滿了之后,觸發(fā)擴(kuò)容機(jī)制。

          如圖所示。

          現(xiàn)在,清晰了吧?

          那怎么append時,從0開始呢???

          這不是很簡單,直接讓第二個參數(shù)為0。

          var names = make([]int010)//結(jié)果:[11 23 231]

          如圖所示。

          好了,這個,懂了吧,怎么繼續(xù)哈。


          為什么不推薦使用var []類型方式創(chuàng)建切片

          我們上述一直在提一個詞,自動擴(kuò)容

          我們來看這樣一段普通的代碼。

          package main
          import "fmt"
          func main() { var names []int //地址:0x0,長度(len):0,容量(cap):0 fmt.Printf("地址:%p,長度(len):%d,容量(cap):%d\n", names, len(names), cap(names)) names = append(names, 123)
          //地址:0xc000010380,長度(len):3,容量(cap):4 fmt.Printf("地址:%p,長度(len):%d,容量(cap):%d\n", names, len(names), cap(names))}

          雖然按照這種方法,使用append動態(tài)添加是沒問題的。

          在不使用make聲明數(shù)組時,lencap都是0,并且地址也是一個值。

          通過append之后,可以明顯看到,地址發(fā)生了改變,因為又重新申請了數(shù)組,切片重新指向新的數(shù)組。

          lencap也發(fā)生了變化。


          copy復(fù)制切片

          package main
          import "fmt"
          func main() { var names1 = make([]string010) names1 = append(names1, "張三") names1 = append(names1, "李四") var names2 = names1 //將names1賦值到names2 fmt.Println(names1, names2) //[張三 李四] [張三 李四] names1[0] = "張三666"//修改names下標(biāo)為0的值為 張三666 fmt.Println(names1, names2) //[張三666 李四] [張三666 李四] //為什么修改names1的值,會影響names2的值????}

          為什么修改names1的值,會影響names2的值???

          這個,就又要回到內(nèi)存分布圖了,如圖所示。

          我們說過很多次,不管是打印,還是賦值等操作,只會操作上面存儲的

          當(dāng)names2=names1時,只會把names1棧上面的地址,給names2

          但是存的時堆上面的地址,終究還是指向了同一個堆。

          所以修改names1時,names2也修改了。


          那如果不想出現(xiàn)上述問題怎么辦???

          解決辦法:使用copy

          package main
          import "fmt"
          func main() { var names1 = make([]string010) names1 = append(names1, "張三") names1 = append(names1, "李四") //定義一個names2切片用于接收,第二個參數(shù)要留空間,names1里面又幾個元素,names2第二個參數(shù)也要是幾 var names2 = make([]string210) copy(names2, names1)//將names1的值,賦值到names2 fmt.Println(names1, names2) //[張三 李四] [張三 李四] names1[0] = "張三666"//修改names下標(biāo)為0的值為 張三666 fmt.Println(names1, names2) //[張三666 李四] [張三 李四] fmt.Printf("names1地址:%p names2地址:%p\n",names1,names2) //names1地址:0xc00009a0a0 names2地址:0xc00009a140}

          內(nèi)存圖

          自動擴(kuò)容機(jī)制

          非常抱歉,我不會。。。


          總結(jié)

          上述我們學(xué)習(xí)了Go基礎(chǔ)之切片補(bǔ)充。如果在操作過程中有任務(wù)問題,記得在下面的討論區(qū)留言,我們看到會第一時間解決問題。

          我是碼農(nóng)星期八,如果覺得還不錯,記得動手點贊一下哈。感謝你的觀看。

          -------------------?End?-------------------

          歡迎大家點贊轉(zhuǎn)發(fā),轉(zhuǎn)載,感謝大家的相伴與支持

          想加入學(xué)習(xí)群請在后臺回復(fù)【入群

          萬水千山總是情,點個【在看】行不行

          瀏覽 35
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  天天天天澡日日日日澡无码 | 一级黄色电影在线观看 | 欧美一级操逼逼 | 玖玖精品视频一区二区三区四区 | 无码免费高清 |