速戰速決 go https://github.com/webabcd/GoSample
作者 webabcd
速戰速決 go - go 容器: 切片(通過範圍獲取切片,切片的構造,切片數據的添加/複製/刪除,數組和切片的區別)
示例如下:
container/slice.go
// go 容器 - 切片(通過範圍獲取切片,切片的構造,切片數據的添加/複製/刪除,數組和切片的區別)
// 數組是內存中的一段連續空間,切片是對數組的某一段連續空間的引用
// 數組是固定長度的,切片是長度可變的
// 數組是指針指向的值,切片是一個指針(也就是所謂的數組是值類型,切片是引用類型)
package container
import (
"fmt"
"reflect"
)
func SliceSample() {
slice_sample1()
slice_sample2()
slice_sample3()
slice_sample4()
slice_sample5()
slice_sample6()
}
// 從數組或切片中獲取指定範圍的切片
func slice_sample1() {
var a = [5]int{1, 2, 3, 4, 5}
// 獲取指定位置範圍的切片(左閉右開原則,即包括左邊,不包括右邊)
fmt.Println(a[0:3]) // [1 2 3]
fmt.Println(a[:5]) // [1 2 3 4 5]
fmt.Println(a[0:]) // [1 2 3 4 5]
fmt.Println(a[0:0]) // []
fmt.Println(a[:]) // [1 2 3 4 5]
// a 是數組,它是固定長度的
fmt.Println(reflect.TypeOf(a)) // [5]int
// a[:] 是切片,它的長度是可變的
fmt.Println(reflect.TypeOf(a[:])) // []int
// 注:切片之間是不能通過 == 做相等判斷的,下面這句會編譯時報錯
// fmt.Println(a[:] == a[:])
}
// 構造切片
func slice_sample2() {
// 構造一個切片
// 第 2 個參數表示切片初始化時元素的個數
// 第 3 個參數表示初始化時,爲切片分配的初始空間的長度
// 如果不指定此參數,則其值同第 2 個參數
// 後續,如果切片中的元素個數發生了變化,系統會根據它自己的邏輯決定是否重新分配空間
var a []int = make([]int, 2)
b := make([]int, 2, 10)
// 構造一個切片,並初始化(與數組的區別是 [] 裏面啥都沒有)
c := []int{0, 0}
// len() - 獲取切片的長度
// cap() - 獲取切片的佔用空間的長度
fmt.Println(a, b, c, len(a), len(b), len(c), cap(a), cap(b), cap(c)) // [0 0] [0 0] [0 0] 2 2 2 2 10 2
}
// 在切片的頭部或尾部添加數據
func slice_sample3() {
a := []int{}
// 在尾部添加元素
a = append(a, 0, 1, 2)
a = append(a, []int{3, 4, 5}...)
fmt.Println(a) // [0 1 2 3 4 5]
// 在開頭添加元素
a = append([]int{-3, -2, -1}, a...)
fmt.Println(a) // [-3 -2 -1 0 1 2 3 4 5]
}
// 切片的複製
func slice_sample4() {
a := []int{1, 2, 3, 4, 5}
b := make([]int, 10)
c := make([]int, 10)
// 將 a 複製給 b(返回值爲複製的元素個數)
d := copy(b, a)
// 將 a[2:5] 複製給 c[2:5](返回值爲複製的元素個數)
e := copy(c[2:5], a[2:5])
fmt.Println(a, b, c, d, e) // [1 2 3 4 5] [1 2 3 4 5 0 0 0 0 0] [0 0 3 4 5 0 0 0 0 0] 5 3
}
// 切片中元素的刪除
func slice_sample5() {
a := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18}
fmt.Println(a) // [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18]
a = a[2:] // 刪除開頭 2 個元素
a = a[:len(a)-2] // 刪除尾部 2 個元素
fmt.Println(a) // [3 4 5 6 7 8 9 10 11 12 13 14 15 16]
a = append(a[:0], a[2:]...) // 刪除開頭 2 個元素
a = a[:copy(a, a[2:])] // 刪除開頭 2 個元素
fmt.Println(a) // [7 8 9 10 11 12 13 14 15 16]
a = append(a[:2], a[5:]...) // 刪除索引位置 2 到 4 之間的 3 個元素
a = a[:2+copy(a[2:], a[5:])] // 刪除索引位置 2 到 4 之間的 3 個元素
fmt.Println(a) // [7 8 15 16]
}
// 數組和切片的區別
func slice_sample6() {
// 數組,固定長度
a := [3]int{1, 2, 3}
// 切片,長度可變
b := []int{1, 2, 3}
// 數組 a 是指針指向的值
// 切片 b 是一個指針
fmt.Printf("%v, %v, %T, %T, %p, %p\n", a, b, a, b, &a, b) // [1 2 3], [1 2 3], [3]int, []int, 0xc00000e168, 0xc00000e180
// 切片是對數組的一段連續區域的引用
c := a[:2]
d := a[1:]
// 所以指針 &a 和指針 c 是一樣的,而指針 &a 和指針 d 是不一樣的
fmt.Printf("%v, %v, %v, %p, %p, %p\n", a, c, d, &a, c, d) // [1 2 3], [1 2], [2 3], 0xc00000e168, 0xc00000e168, 0xc00000e170
}
速戰速決 go https://github.com/webabcd/GoSample
作者 webabcd