切片维护了三个元素:
指向底层数组的指针,切片的元素数量和底层数组的容量。由于有指针的存在,所以切片是引用类型
若多个切片由同一数组而来,则对数组的修改将影响全局
package main
import "fmt"
/*
切片的本质就是一个框,框住了一块连续的内存
属于引用类型,真正的数据保存在底层数组中
*/
func main() {
//普通slice
var slice_1 bool = false
if slice_1 {
var a []string
a = append(a, "hello")
fmt.Println(a, len(a), cap(a))
var b [][]string = [][]string{
[]string{"hello"},
[]string{"world"},
}
fmt.Println(b)
}
//由数组得到切片
//切片的长度是元素的个数,切片的容量是底层数组从切片的第一个元素到最后一个元素的数量
var slice_2 bool = false
if slice_2 {
a1 := [...]int64{1, 3, 5, 7}
a2 := a1[0:3] //基于一个数组进行切割,左闭右开,包左不包右
fmt.Print("len:", len(a2), " cap:", cap(a2), "\n")
a3 := a1[1:]
fmt.Println(a3)
}
//从切片再切片时,会将a1构造成数组,
//切片是引用类型,都指向底层的数组
var slice_3 bool = false
if slice_3 {
a1 := []int{1, 3, 5, 7, 9, 11}
a2 := a1[0:3]
fmt.Print("len:", len(a2), " cap:", cap(a2), "\n")
a1[0] = 9
fmt.Println("a1[0]:", a1[0], " a2[0]:", a2[0])
a2[1] = 9
fmt.Println("a1[1]:", a1[1], " a2[1]:", a2[1])
}
//a[low:high]为简单的切片表达式
//a[low:high:max]为完整的切片表达式,与简单切片表达式a[low:high]想同类型,相同长度和元素的切片。另外,它会将得到的结果切片容量设置为max - low
//在完整切片表达式中只有第一个索引值low可以省略,省略时默认为0,并且max需要大于hight
var slice_4 bool = false
if slice_4 {
a1 := []int{1, 3, 5, 7, 9, 11}
a2 := a1[0:4]
a3 := a1[0:4:5]
fmt.Printf("a2 t:%v len(t):%v cap(t)%v\n", a2, len(a2), cap(a2)) //len(t):4 cap(t)6
fmt.Printf("a3 t:%v len(t):%v cap(t)%v\n", a3, len(a3), cap(a3)) //len(t):4 cap(t)5
}
/*
make函数构造切片 make([]Type, len, cap) Type cap省略时,cap==len
第二个整数参数可以提供给
指定不同的容量; 它必须不小于长度。 例如,make([]int, 0, 10) 分配一个底层数组
大小为 10 并返回长度为 0 且容量为 10 的切片,即由这个底层数组支持
*/
var slice_5 bool = false
if slice_5 {
a1 := make([]int, 5, 10)
fmt.Printf("a1 t:%v len(t):%v cap(t)%v\n", a1, len(a1), cap(a1))
}
/*
切片不能直接比较,不能使用==判断两个切片是否含有全部相等元素
唯一合法的 *** 作时和nil比较,一个nil的切片并没有底层数组,即长度和容量0
但是长度和容量为0的切片不一定是nil
*/
}
切片的复制,删除和拼接
package main
import "fmt"
/*
切片的本质就是一个框,框住了一块连续的内存
属于引用类型,真正的数据保存在底层数组中
*/
func main() {
var slice_1 bool = false
//append追加元素 扩容策略可在 $GOROOT/src/runtime/slice.go
if slice_1 {
a1 := make([]string, 0, 10)
fmt.Println("len:", len(a1), " cap:", cap(a1))
a1 = append(a1, "hello")
fmt.Println("len:", len(a1), " cap:", cap(a1))
}
var slice_2 bool = false
//copy 复制切片,避免了浅拷贝
if slice_2 {
a1 := make([]int64, 1, 5)
a2 := a1
a1[0] = 1
fmt.Println("len:", len(a1), " cap:", cap(a1), " a1[0]:", a1[0])
fmt.Println("len:", len(a2), " cap:", cap(a2), " a2[0]:", a2[0])
a1 = append(a1, a2...)
fmt.Println("len:", len(a1), " cap:", cap(a1), " ", a1[0], a1[1])
fmt.Println("len:", len(a2), " cap:", cap(a2), " ", a2[0])
a3 := []int{1, 3, 5}
// var a4 []int //此时a4无内存 为nil 无法拷贝,应该使用make
a4 := make([]int, 2, 5)
copy(a4, a3)
fmt.Println(a3, a4) //实际被copy过去的长度为2和3的交集 也就是2
}
/*
没有删除元素的方法, 如果要从切片a中删除下标为index的元素
*** 作方法为 a = append(a[:index], a[index + 1:]...)
*/
var slice_3 bool = false
if slice_3 {
a := []int{1, 3, 5, 7, 9}
a = append(a[:2], a[3:]...)
fmt.Println(a)
fmt.Println(cap(a)) //cap仍然是5
x1 := [5]int{1, 3, 5, 7, 9}
a2 := x1[:]
a2 = append(a2[:2], a2[3:]...)
fmt.Println("x1:", x1) //[1 5 5 7 9]
fmt.Println("a2:", a2, " cap(a2):", cap(a2), " len(a2):", len(a2))
a3 := make([]int, 5, 10)
for i := 0; i < 10; i++ {
a3 = append(a3, i)
}
fmt.Println("a3:", a3)
}
//关于append删除切片中的某个元素
var slice_4 bool = true
if slice_4 {
a1 := [...]int{1, 3, 5, 7, 9, 11, 13, 17}
s1 := a1[:]
s1 = append(s1[:1], s1[2:]...)
fmt.Println(s1)
fmt.Println(a1)
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)