一篇文章帶你瞭解 Go 語言基礎之切片

前言

Hey,大家好呀,我是星期八,這次咱們繼續學習 Go 基礎之切片扒。

爲什麼需要切片

在原來的時候,我們學過數組,我們知道數組是可以存儲很多東西的。

代碼

package main
import "fmt"
func main() {
    var student_list = [4]string{"張三" "李四" "王五," "小劉"}
    fmt.Println(student_list)
}

上述代碼定義了一個數組,並且存了 4 個值,但是如果存 5 個值或者更多呢。

package main
import "fmt"
func main() {
    //方式一,在創建的時候就多加一個值
    // 只能存4個,多了會報錯,array index 4 out of bounds [0:4]
    //var student_list = [4]string{"張三", "李四", "王五,", "小劉","小七"}
    //方式二,通過索引方式添加值
    var student_list = [4]string{"張三" "李四" "王五," "小劉"}
    //還是會報錯,invalid array index 4 (out of bounds for 4-element array)
    //student_list[4] = "小七"
    fmt.Println(student_list)
}

結論: 數組只能存儲固定長度,不能追加值,如果追加值會報錯。

所以,就引出了以下的一個鏈式存儲結構。

切片

切片,在其他語言中,在Python中叫列表,Java中好像也是列表,PHP中也叫列表,只是在Go中叫切片 (slice)

切片 (列表) 在每個編程語言中,都是一個非常通用的存儲結構。

屬於堆內存存儲,其內存分佈圖如下。

如何驗證。

package main
import "fmt"
func main() {
    var student_list = []string{"張三" "李四"}         //[]裏面沒有加長度是切片
    var student_list2 = [3]string{"張三" "李四" "王五"} //[]裏面加長度是數組
    fmt.Printf("%p\n" student_list)                //結果:0xc000096440
    fmt.Printf("%p\n" student_list2)               //結果:%!p([3]string=[張三 李四 王五]),表示不是地址
}
/*
    %p表示直接打印的是變量地址
    如果是棧中存儲的,是打印不出來地址的,顯示%!p,表示不是地址
    如果是堆中存儲,打印的就直接是地址
*/

ps: 默認打印,賦值等操作,操作的是棧上面的值,所以堆存儲直接打印的就是堆的地址,賦值等其他操作同理。

開始使用切片

官話

切片(Slice)是一個擁有相同類型元素的可變長度的序列。它是基於數組類型做的一層封裝。它非常靈活,支持自動擴容。

切片是一個引用類型 (堆存儲),它的內部結構包含地址長度容量。切片一般用於快速地操作一塊數據集合。

聲明切片

語法如下。

方式一 (聲明變量方式)

語法
var 變量名 []存儲類型
例如:
package main
/*
    和數組操作方式非常像,[]不加數字,就是切片
*/
func main() {
    var student_list []string
    var student_list2 []int
    var student_list3 []float64
    //類型推斷方式,後面必須帶{},數組同理
    var student_list4 = []string{}
}

方式二 (make 方式)

語法:
var 變量名 = make([]存儲類型 切片中元素數量 切片的容量)
變量名 := make([]int 10 20)
/*
    切片容量不寫等於切片元素數量
*/
例如:
package main
import "fmt"
func main() {
    var student_list4 = make([]int 10 20)
    fmt.Println(student_list4)//結果:[0 0 0 0 0 0 0 0 0 0]
}

由數組得到的切片

注: 數組得到的,只能是切片

package main
import "fmt"
func main() {
    var name_array = [5]int{1 2 3 4 5}
    var name_slice = name_array[1:3] //name_array[1:3]切完值以後,結果只能是切片
    fmt.Printf("%T %T\n" name_array name_slice)
}

ps: 數組通過下標範圍 ([開始下標:結束下標]) 的方式獲取的值,只能是列表,取值包含左下標,不包含右下標

簡稱顧左不顧右。

向切片中追加元素 (增)

終於到了每個語言的必學的環節了,切片的增加操作。

在 Go 中,向切片中追加值,需要用到 append。

package main
import "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 之後,必須使用原來的變量再接受一次

一次性增加多個

如果一個列表,需要增加另外一個列表怎麼辦呢???

package main
import "fmt"
func main() {
    //var student_list []string
    var student_list1 = []string{"張三" "李四" "王五" "小劉"}
    var student_list2 = make([]string 10)
    student_list2 = append(student_list2 "八神")       //添加一個值
    student_list2 = append(student_list2 "八神" "九尾") //可以添加多個值
    student_list2 = append(student_list2 student_list1...)
    //下面這種寫法,就是上面...所包含的意思,專業叫法叫做打散,
    //student_list2 = append(student_list2,"張三", "李四", "王五", "小劉")
    fmt.Println(student_list2) //[          八神 張三 李四 王五 小劉]
}

注: 可能有人會注意到,八神前面會有很多空格,這個先彆着急,後面揭曉。

修改切片中的元素 (改)

修改就簡單了,同數組。

package main
import "fmt"
func main() {
    var names = []string{"張三" "李四"}
    names[1] = "李四666" //修改下標爲1的值
    fmt.Println(names) //[張三 李四666]
}

刪除切片中的元素 (刪)


比較尷尬的是,Go 中的切片,在做刪除這個操作,不是太友好。

下面舉個例子,希望能看懂,看不懂會用就行。

package main
import "fmt"
func main() {
    var names = []string{"張三" "李四" "王五" "小劉" "七阿"}
    //刪除索引爲2的元素
    names = append(names[:2] names[3:]...) //刪除王五
    fmt.Println(names)                      //[張三 李四 小劉 七阿]
}

如果看不懂,沒關係,下章會好好捋捋這個。

切片遍歷 (查)

切片的遍歷同數組一樣。

package main
import "fmt"
func main() {
    var names = []string{"張三" "李四" "王五" "小劉" "七阿"}
    //方式一,標準for循環
    for i := 0; i < len(names); i++ {
        fmt.Println(names[i])
}
    //方式二,for range
    for index value := range names {
        //index爲下標,value爲值
        fmt.Println(index value)
  }
}

總結


上述我們學習了 Go 基礎之切片。如果在操作過程中有任務問題,記得在下面的討論區留言,我們看到會第一時間解決問題。

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

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/ZhzYQFihgE3Ymi2fFNVoVw