GO語言學習——切片三 append()方法為切片添加元素、切片的擴容策略、使用copy()函數複製切片、從切片中刪除元素
append()方法為切片添加元素
注意:通過var聲明的零值切片可以在append()函數直接使用,無需初始化。
var s []int
s = append(s, 1, 2, 3)
- append()函數將元素追加到切片的最後並返回該切片。
- 切片numSlice的容量按照1,2,4,8,16這樣的規則自動進行擴容,每次擴容後都是擴容前的2倍。
切片的擴容策略
查看$GOROOT/src/runtime/slice.go源碼
package main
import "fmt"
// append() 為切片追加元素
func main(){
s1 := []string{"北京", "上海", "深圳"}
fmt.Printf("s1=%v len(s1)=%d cap(s1)=%d\n", s1, len(s1), cap(s1))
// s1[3] = "廣州" // 錯誤的寫法 會導致編譯錯誤:索引越界
// fmt.Println(s1) // index out of range [3] with length 3
// 調用append函數必須用原來的切片變數接收返回值
// append追加元素 原來的底層數組放不下的時候 Go語言就會把底層數組換一個
// 必須用變數接收append的返回值
fmt.Println(s1)
s1 = append(s1, "廣州")
fmt.Printf("s1=%v len(s1)=%d cap(s1)=%d\n", s1, len(s1), cap(s1))
s1 = append(s1, "杭州", "成都")
fmt.Printf("s1=%v len(s1)=%d cap(s1)=%d\n", s1, len(s1), cap(s1))
ss := []string{"武漢", "西安", "蘇州"}
s1 = append(s1, ss...) // ...表示拆開
fmt.Printf("s1=%v len(s1)=%d cap(s1)=%d\n", s1, len(s1), cap(s1))
}
使用copy()函數複製切片
copy()函數的格式:
copy(destSlice, srcSlice []T)
其中:
- srcSlice: 數據來源切片
- destSlice: 目標切片
從切片中刪除元素
package main
import "fmt"
// 關於append刪除切片中的某個元素
func main(){
a1 := [...]int{1,3,5,7,9,11,13,15,17}
s1 := a1[:]
// 刪除索引為1的那個3
s1 = append(s1[0:1], s1[2:]...)
fmt.Println(s1) // [1 5 7 9 11 13 15 17]
fmt.Println(a1) // [1 5 7 9 11 13 15 17 17]
}
切片不存值 底層數組存值
package main
import "fmt"
// copy
func main() {
a1 := []int{1,3,5}
a2 := a1 // 賦值
// var a3 []int // nil
var a3 = make([]int, 3, 3)
copy(a3, a1) // copy
fmt.Println(a1, a2, a3)
a1[0] = 100
fmt.Println(a1, a2, a3)
// 將a1中的索引為1的3這個元素刪除
a1 = append(a1[:1], a1[2:]...)
fmt.Println(a1)
fmt.Println(cap(a1))
x1 := [...]int{1, 3, 5} // 數組
s1 := x1[:]
fmt.Println(s1, len(s1), cap(s1))
// 1. 切片不保存具體的值
// 2. 切片對應一個底層數組
// 3. 底層數組都是佔用一塊連續的記憶體
fmt.Printf("%p\n", &s1[0])
s1 = append(s1[:1], s1[2:]...) // 修改了底層數組!
fmt.Printf("%p\n", &s1[0])
fmt.Println(s1, len(s1), cap(s1))
// ?
// s1[0] = 100 // 修改底層數組
fmt.Println(x1) // [1 5 5]
}
練習題
package main
import (
"fmt"
"sort"
)
// 切片的練習題
func main() {
var a = make([]int, 5, 10) // 創建切片 長度為5 容量為10
fmt.Println(a) // [0 0 0 0 0]
for i := 0; i < 10; i++ {
a = append(a, i)
}
fmt.Println(a) // [0 0 0 0 0 0 1 2 3 4 5 6 7 8 9]
fmt.Println(cap(a))
// sort排序
var a1 = [...]int{3, 7, 8, 9, 1}
sort.Ints(a1[:]) // 對切片進行排序
fmt.Println(a1)
}