12.slice切片宣告、擷取操作
阿新 • • 發佈:2021-10-08
1.四種宣告方式示例程式碼
slice.go
package chapter09 import "fmt" // Run func Run() { // 方式1:宣告slice1 是一個切片,並且初始化,預設值是1,2,3,長度是3 slice1 := []int{1, 2, 3} fmt.Printf("len = %d, slice1 = %v\n", len(slice1), slice1) // 方式2:宣告slice2一個切片,但是並沒有給slice2分配空間 var slice2 []int slice2 = make([]int, 3) // 通過make開闢3個空間,預設值是0 slice2[0] = 100 fmt.Printf("len = %d, slice2 = %v\n", len(slice2), slice2) // 方式3:宣告slice3一個切片,同時給slice3分配空間,3個空間,預設值是0 var slice3 []int = make([]int, 3) // 通過make開闢3個空間,預設值是0 fmt.Printf("len = %d, slice3 = %v\n", len(slice3), slice3) // 方式4:宣告slice4一個切片,同時給slice4分配空間,3個空間,預設值是0,通過 := 推匯出 slice4是一個切片 slice4 := make([]int, 3) // 通過make開闢3個空間,預設值是0 fmt.Printf("len = %d, slice4 = %v\n", len(slice4), slice4) // 判斷一個切片是否為0 var slice5 []int if len(slice5) == 0 { // if slice5 == nil { fmt.Println("slice5 是一個空切片") } else { fmt.Println("slice5 是有空間的") } }
slice_test.go
package chapter09
import "testing"
func TestRun(t *testing.T) {
Run()
}
執行結果
=== RUN TestRun
len = 3, slice1 = [1 2 3]
len = 3, slice2 = [100 0 0]
len = 3, slice3 = [0 0 0]
len = 3, slice4 = [0 0 0]
slice5 是一個空切片
--- PASS: TestRun (0.00s)
PASS
ok
2.切片的追加操作
2.1.示例程式碼
slice2.go
package chapter09 import "fmt" func Run2() { var numbers = make([]int, 3, 5) // 宣告 長度為3 ,容量為5的 int 切片 fmt.Printf("len = %d, cap = %d, slice = %v\n", len(numbers), cap(numbers), numbers) // 向 numbers 切片追加一個元素 1, numbers len = 4, [0,0,0,1], cap = 5 numbers = append(numbers, 1) fmt.Printf("len = %d, cap = %d, slice = %v\n", len(numbers), cap(numbers), numbers) // 向 numbers 切片追加一個元素 1, numbers len = 5, [0,0,0,1.2], cap = 5 numbers = append(numbers, 2) fmt.Printf("len = %d, cap = %d, slice = %v\n", len(numbers), cap(numbers), numbers) // 向一個容量cap已經滿的slice 追加元素 numbers = append(numbers, 3) fmt.Printf("len = %d, cap = %d, slice = %v\n", len(numbers), cap(numbers), numbers) fmt.Println("----------") var numbers2 = make([]int, 3) fmt.Printf("len = %d, cap = %d, slice = %v\n", len(numbers2), cap(numbers2), numbers2) numbers2 = append(numbers2, 1) fmt.Printf("len = %d, cap = %d, slice = %v\n", len(numbers2), cap(numbers2), numbers2) }
執行結果
=== RUN TestRun2
len = 3, cap = 5, slice = [0 0 0]
len = 4, cap = 5, slice = [0 0 0 1]
len = 5, cap = 5, slice = [0 0 0 1 2]
len = 6, cap = 10, slice = [0 0 0 1 2 3]
----------
len = 3, cap = 3, slice = [0 0 0]
len = 4, cap = 6, slice = [0 0 0 1]
--- PASS: TestRun2 (0.00s)
PASS
ok
圖示解說
動態開闢空間之前
動態開闢空間之後
2.2.總結
3.切片的擷取操作
示例程式碼
slice3.go
package chapter09
import "fmt"
func Run3() {
s := []int{1, 2, 3} // len = 3 , cap = 3 , [1, 2, 3]
// [0,2)
s1 := s[0:2] // [1, 2]
fmt.Println(s1)
s1[0] = 100
fmt.Println("s = ", s)
fmt.Println("s1 = ", s)
// copy 可以將底層陣列的slice一起進行拷貝
s2 := make([]int, 3) // s2 = [0, 0, 0]
// 將s中的值,依次拷貝到s2中
copy(s2, s)
fmt.Println("s2 = ", s2)
}
執行結果
=== RUN TestRun3
[1 2]
s = [100 2 3]
s1 = [100 2 3]
s2 = [100 2 3]
--- PASS: TestRun3 (0.00s)
PASS
ok
copy的圖示
copy前
copy後
4.總結
- 切片的宣告(四種方式)
- 方式1:
slice1 := []int{1, 2, 3}
, 宣告+賦值操作 - 方式2:
var slice2 []int
宣告和空間分配相互獨立,採用
slice2 = make([]int, 3)make
進行切片空間分配 - 方式3:
var slice3 []int = make([]int, 3)
簡化方式2 - 方式4:slice4 := make([]int, 3) , 使用的是型別推導的方式
- 方式1:
- 切片的追加
- 如果聲明瞭容量,追加元素後,切片的長度未達到容量的大小,不進行擴容;但是到達容量閾值時,進行2倍的方式進行擴容。
- 如果沒有指定容量,追加元素,長度到達容量閾值容量,進行2倍的形式擴容。
- 切片的擷取
- 擷取的切片指標與元切片共享一個記憶體地址
- copy 是 為切片,從新開闢新的記憶體地址