數組元素固定,在 Go 語言中沒有那麼常用,更常用的數據結構是切片。什麼是切片呢? 切片就是動態的數組,它的長度不固定,可以隨意向切片中追加元素,而且切片會在容量不足的時候自動擴容。切片(slice)是對數組一個連續片段的引用,這個片段可以是整個數組,或者是由起始和終止索引標識的一些項的子集,需要註 ...
數組元素固定,在 Go 語言中沒有那麼常用,更常用的數據結構是切片。
什麼是切片呢? 切片就是動態的數組,它的長度不固定,可以隨意向切片中追加元素,而且切片會在容量不足的時候自動擴容。
切片(slice)是對數組一個連續片段的引用,這個片段可以是整個數組,或者是由起始和終止索引標識的一些項的子集,需要註意的是,終止索引標識的項不包括在切片內,切片提供了一個與指向數組的動態視窗。
切片的數據結構如下:
type slice struct { // Pointer 是指向一個數組的指針 array unsafe.Pointer // 當前切片的長度 len int // cap 是當前切片的容量。cap 總是大於等於 len 的。 cap int }
Pointer 作為一個指針指向的數組是一片連續的記憶體空間,這片記憶體空間可以用於存儲切片中保存的全部元素,底層存儲都是連續的,所以可以將切片理解為一片連續的記憶體空間加上長度與容量的標識。
實戰需求: slice 切片的實現原理
馬上安排!
一、工程目錄
cd go-003/
二、創建 g003.go
/* * @Author: 菜鳥實戰 * @FilePath: /go110/go-003/g003.go * @Description: slice 切片 */ package main import ( "fmt" "runtime" ) // 主函數 func main() { // 使用內置函數列印 println("Hello", "菜鳥實戰") //定義一個無初始長度的切片 s := []string{} for i := 0; i < 6; i++ { // 拼接元素 s = append(s, "eeeee") // 拼接後會動態擴容 fmt.Printf("容量: %v, 長度 : %v \n", cap(s), len(s)) } // 使用包函數列印 fmt.Printf("版本: %s \n", runtime.Version()) }
三、編譯和運行
# 1、生成模塊依賴
go mod init g003# 2、編譯
go build g003.go# 3、編譯後的目錄結構
└── go-003 ├── g003 ├── g003.go └── go.mod# 4、運行
go run g003
四、運行結果
Hello 菜鳥實戰
容量: 1, 長度 : 1
容量: 2, 長度 : 2
容量: 4, 長度 : 3
容量: 4, 長度 : 4
容量: 8, 長度 : 5
容量: 8, 長度 : 6
版本: go1.17.10
由輸出結果可以看到,Slice 的容量會自動擴容的起點是 2,當長度大於 2 時,slice 的容量會自動擴容為原來的 2 倍,每一次擴容都會重新開闢一塊記憶體空間,將舊的數據複製到新開闢的記憶體空間中,然後釋放舊的記憶體空間。
數組長度是固定的,而 Go 中使用的切片設計想法是由動態數組概念而來,可以用來管理數據集合,並可以自動增加和減少,但是切片本身並不是動態數據或者數組指針,與此同時,切片還具有可索引,可迭代的優秀特性,因此使用也更為廣範。
菜鳥實戰,持續學習!