一篇文章帶你瞭解 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