一篇文章帶你了解Go語(yǔ)言基礎(chǔ)之切片
回復(fù)“Go語(yǔ)言”即可獲贈(zèng)Python從入門(mén)到進(jìn)階共10本電子書(shū)
????上篇文章中我們學(xué)習(xí)了Go語(yǔ)言基礎(chǔ)中的變量,一篇文章帶你了解Go語(yǔ)言基礎(chǔ)之變量,這篇文章我們繼續(xù)介紹Go語(yǔ)言基礎(chǔ)知識(shí),今天跟大家分享的是基礎(chǔ)數(shù)據(jù)類型之切片,一起來(lái)學(xué)習(xí)下吧~
前言
Hey,大家好呀,我是星期八,這次咱們繼續(xù)學(xué)習(xí)Go基礎(chǔ)之切片扒。
為什么需要切片
在原來(lái)的時(shí)候,我們學(xué)過(guò)數(shù)組,我們知道數(shù)組是可以存儲(chǔ)很多東西的。
代碼
package mainimport "fmt"func main() {var student_list = [4]string{"張三", "李四", "王五,", "小劉"}fmt.Println(student_list)}
上述代碼定義了一個(gè)數(shù)組,并且存了4個(gè)值,但是如果存5個(gè)值或者更多呢。
package mainimport "fmt"func main() {//方式一,在創(chuàng)建的時(shí)候就多加一個(gè)值// 只能存4個(gè),多了會(huì)報(bào)錯(cuò),array index 4 out of bounds [0:4]//var student_list = [4]string{"張三", "李四", "王五,", "小劉","小七"}//方式二,通過(guò)索引方式添加值var student_list = [4]string{"張三", "李四", "王五,", "小劉"}//還是會(huì)報(bào)錯(cuò),invalid array index 4 (out of bounds for 4-element array)//student_list[4] = "小七"fmt.Println(student_list)}
結(jié)論:數(shù)組只能存儲(chǔ)固定長(zhǎng)度,不能追加值,如果追加值會(huì)報(bào)錯(cuò)。
所以,就引出了以下的一個(gè)鏈?zhǔn)酱鎯?chǔ)結(jié)構(gòu)。
切片
切片,在其他語(yǔ)言中,在Python中叫列表,Java中好像也是列表,PHP中也叫列表,只是在Go中叫切片(slice)
切片(列表)在每個(gè)編程語(yǔ)言中,都是一個(gè)非常通用的存儲(chǔ)結(jié)構(gòu)。
屬于堆內(nèi)存存儲(chǔ),其內(nèi)存分布圖如下。

如何驗(yàn)證。
package mainimport "fmt"func main() {var student_list = []string{"張三", "李四"} //[]里面沒(méi)有加長(zhǎng)度是切片var student_list2 = [3]string{"張三", "李四", "王五"} //[]里面加長(zhǎng)度是數(shù)組fmt.Printf("%p\n", student_list) //結(jié)果:0xc000096440fmt.Printf("%p\n", student_list2) //結(jié)果:%!p([3]string=[張三 李四 王五]),表示不是地址}/*%p表示直接打印的是變量地址如果是棧中存儲(chǔ)的,是打印不出來(lái)地址的,顯示%!p,表示不是地址如果是堆中存儲(chǔ),打印的就直接是地址*/
ps:默認(rèn)打印,賦值等操作,操作的是棧上面的值,所以堆存儲(chǔ)直接打印的就是堆的地址,賦值等其他操作同理。
開(kāi)始使用切片
官話
切片(Slice)是一個(gè)擁有相同類型元素的可變長(zhǎng)度的序列。它是基于數(shù)組類型做的一層封裝。它非常靈活,支持自動(dòng)擴(kuò)容。
切片是一個(gè)引用類型(堆存儲(chǔ)),它的內(nèi)部結(jié)構(gòu)包含地址,長(zhǎng)度和容量。切片一般用于快速地操作一塊數(shù)據(jù)集合。
聲明切片
語(yǔ)法如下。
方式一(聲明變量方式)
語(yǔ)法var 變量名 []存儲(chǔ)類型例如:package main/*和數(shù)組操作方式非常像,[]不加數(shù)字,就是切片*/func main() {var student_list []stringvar student_list2 []intvar student_list3 []float64//類型推斷方式,后面必須帶{},數(shù)組同理var student_list4 = []string{}}
方式二(make方式)
語(yǔ)法:var 變量名 = make([]存儲(chǔ)類型, 切片中元素?cái)?shù)量, 切片的容量)變量名 := make([]int, 10, 20)/*切片容量不寫(xiě)等于切片元素?cái)?shù)量*/例如:package mainimport "fmt"func main() {var student_list4 = make([]int, 10, 20)fmt.Println(student_list4)//結(jié)果:[0 0 0 0 0 0 0 0 0 0]}
由數(shù)組得到的切片
注:數(shù)組得到的,只能是切片
package mainimport "fmt"func main() {var name_array = [5]int{1, 2, 3, 4, 5}var name_slice = name_array[1:3] //name_array[1:3]切完值以后,結(jié)果只能是切片fmt.Printf("%T %T\n", name_array, name_slice)}
ps:數(shù)組通過(guò)下標(biāo)范圍([開(kāi)始下標(biāo):結(jié)束下標(biāo)])的方式獲取的值,只能是列表,取值包含左下標(biāo),不包含右下標(biāo)
簡(jiǎn)稱顧左不顧右。
向切片中追加元素(增)
終于到了每個(gè)語(yǔ)言的必學(xué)的環(huán)節(jié)了,切片的增加操作。
在Go中,向切片中追加值,需要用到append。
package mainimport "fmt"func main() {var student_list []string//append追加之后,必須使用student_list再接收student_list = append(student_list, "張三")student_list = append(student_list, "李四")student_list = append(student_list, "王五")fmt.Println(student_list)}
ps:apppend之后,必須使用原來(lái)的變量再接受一次
一次性增加多個(gè)
如果一個(gè)列表,需要增加另外一個(gè)列表怎么辦呢???
package mainimport "fmt"func main() {//var student_list []stringvar student_list1 = []string{"張三", "李四", "王五", "小劉"}var student_list2 = make([]string, 10)student_list2 = append(student_list2, "八神") //添加一個(gè)值student_list2 = append(student_list2, "八神", "九尾") //可以添加多個(gè)值student_list2 = append(student_list2, student_list1...)//下面這種寫(xiě)法,就是上面...所包含的意思,專業(yè)叫法叫做打散,//student_list2 = append(student_list2,"張三", "李四", "王五", "小劉")fmt.Println(student_list2) //[ 八神 張三 李四 王五 小劉]}
注:可能有人會(huì)注意到,八神前面會(huì)有很多空格,這個(gè)先別著急,后面揭曉。
修改切片中的元素(改)
修改就簡(jiǎn)單了,同數(shù)組。
package mainimport "fmt"func main() {var names = []string{"張三", "李四"}names[1] = "李四666" //修改下標(biāo)為1的值fmt.Println(names) //[張三 李四666]}
刪除切片中的元素(刪)
比較尷尬的是,Go中的切片,在做刪除這個(gè)操作,不是太友好。
下面舉個(gè)例子,希望能看懂,看不懂會(huì)用就行。
package mainimport "fmt"func main() {var names = []string{"張三", "李四", "王五", "小劉", "七阿"}//刪除索引為2的元素names = append(names[:2], names[3:]...) //刪除王五fmt.Println(names) //[張三 李四 小劉 七阿]}
如果看不懂,沒(méi)關(guān)系,下章會(huì)好好捋捋這個(gè)。
切片遍歷(查)
切片的遍歷同數(shù)組一樣。
package mainimport "fmt"func main() {var names = []string{"張三", "李四", "王五", "小劉", "七阿"}//方式一,標(biāo)準(zhǔn)for循環(huán)for i := 0; i < len(names); i++ {fmt.Println(names[i])}//方式二,for rangefor index, value := range names {//index為下標(biāo),value為值fmt.Println(index, value)}}
總結(jié)
上述我們學(xué)習(xí)了Go基礎(chǔ)之切片。如果在操作過(guò)程中有任務(wù)問(wèn)題,記得在下面的討論區(qū)留言,我們看到會(huì)第一時(shí)間解決問(wèn)題。
我是碼農(nóng)星期八,如果覺(jué)得還不錯(cuò),記得動(dòng)手點(diǎn)贊一下哈。感謝你的觀看。
-------------------?End?-------------------

歡迎大家點(diǎn)贊,轉(zhuǎn)發(fā),轉(zhuǎn)載,感謝大家的相伴與支持
想加入學(xué)習(xí)群請(qǐng)?jiān)诤笈_(tái)回復(fù)【入群】
萬(wàn)水千山總是情,點(diǎn)個(gè)【在看】行不行
