Go语言切片
从底层来看,切片引用了数组的对象。切片可以追加元素,在追加时可能使切片的容量增大。与数组相比,切片不需要设定长度,在
 [] 中不用设定值,相对来说比较自由。切片的数据结构可理解为一个结构体,这个结构体包含了三个元素。
- 指针:指向数组中切片指定的开始位置。
- 长度:即切片的长度。
- 容量:也就是切片开始位置到数组的最后位置的长度。
1、切片的语法
1) 声明切片
声明一个未指定长度的数组来定义切片,具体示例如下。var identifier []type
切片不需要说明长度。采用该声明方式且未初始化的切片为空切片。该切片默认为 nil,长度为 0。使用 make() 函数来创建切片,语法格式如下。
var slice1 []type = make([]type, len)
使用 make() 函数来创建切片可以简写为如下格式。slice1 := make([]type, len)
创建切片时可以指定容量,其中 capacity 为可选参数:make([]T, length, capacity)。详情如下所示。
package main
import "fmt"
func main() {
    var numbers = make([]int, 3, 5)
    fmt.Printf("%T\n", numbers)
    fmt.Printf("len=%d cap=%d slice=%v\n", len(numbers), cap(numbers), numbers)
}
运行结果如下:
	[]int
	len=3 cap=5 slice=[0 0 0]
2) 初始化
直接初始化切片,语法格式如下。s := [] int {1, 2, 3}
通过数组截取来初始化切片,语法格式如下。
	arr := [5]int {1, 2, 3, 4, 5}
	s := arr [:]
s := arr[startIndex:endIndex]
将 arr 中从下标 startIndex 到 endIndex-1 下的元素创建为一个新的切片(前闭后开),长度为 endIndex-startIndex。缺省 endIndex 时表示一直到 arr 的最后一个元素,语法格式如下。
s := arr[startIndex:]
缺省 startIndex 时表示从 arr 的第一个元素开始,语法格式如下。s := arr[:endIndex]
可以通过设置下限及上限来设置截取切片:[lower-bound:upper-bound],如下所示。
package main
import "fmt"
func main(){
    /*创建切片*/
    numbers := []int{0, 1, 2, 3, 4, 5, 6, 7, 8}
    printSlice(numbers)
    /*打印原始切片*/
    fmt.Println("numbers ==", numbers)
    /*打印子切片从索引1(包含)到索引4(不包含)*/
    fmt.Println("numbers[1:4] ==", numbers[1:4])
    /*默认下限为0*/
    fmt.Println("numbers[:3] ==", numbers[:3])
    /*默认上限为len(s)*/
    fmt.Println("numbers[4:] ==", numbers[4:])
    /*打印子切片从索引0(包含)到索引2(不包含)*/
    number2 := numbers[:2]
    printSlice(number2)
    /*打印子切片从索引2(包含)到索引5(不包含)*/
    number3 := numbers[2:5]
    printSlice(number3)
}
func printSlice(x []int){
    fmt.Printf("len=%d cap=%d slice=%v \n", len(x), cap(x), x)
}
运行结果如下:
	len=9 cap=9 slice=[0 1 2 3 4 5 6 7 8]
	numbers == [0 1 2 3 4 5 6 7 8]
	numbers[1:4] == [1 2 3]
	numbers[:3] == [0 1 2]
	numbers[4:] == [4 5 6 7 8]
	len=2 cap=9 slice=[0 1]
	len=3 cap=7 slice=[2 3 4]
2、切片是引用类型
切片没有自己的任何数据。它只是底层数组的一个引用。对切片所做的任何修改都将反映在底层数组中。数组是值类型,而切片是引用类型,两者的区别如下所示。
package main
import "fmt"
func main(){
    a := [4]float64{67.7, 89.8, 21, 78}
    b := []int{2, 3, 5}
    fmt.Printf("变量a——地址:%p, 类型:%T, 数值:%v, 长度:%d \n", &a, a, a, len(a))
    fmt.Printf("变量b——地址:%p, 类型:%T, 数值:%v, 长度:%d \n", &b, b, b, len(b))
    c := a
    d := b
    fmt.Printf("变量c——地址:%p, 类型:%T, 数值:%v, 长度:%d \n", &c, c, c, len(c))
    fmt.Printf("变量d——地址:%p, 类型:%T, 数值:%v, 长度:%d \n", &d, d, d, len(d))
    a[1] = 200
    fmt.Println("a=", a, "c=", c)
    d[0] = 100
    fmt.Println("b=", b, "d=", d)
}
运行结果如下:
	变量a——地址:0xc00000c360, 类型:[4]float64, 数值:[67.7 89.8 21 78], 长度:4
	变量b——地址:0xc0000044a0, 类型:[]int, 数值:[2 3 5], 长度:3
	变量c——地址:0xc00000c400, 类型:[4]float64, 数值:[67.7 89.8 21 78], 长度:4
	变量d——地址:0xc000004520, 类型:[]int, 数值:[2 3 5], 长度:3
	a= [67.7 200 21 78] c= [67.7 89.8 21 78]
	b= [100 3 5] d= [100 3 5]
package main
import "fmt"
func main(){
    //定义数组
    arr := [3]int{1, 2, 3}
    //根据数组截取切片
    nums1 := arr[:]
    nums2 := arr[:]
    fmt.Println("arr=", arr)
    nums1[0] = 100
    fmt.Println("arr=", arr)
    nums2[1] = 200
    fmt.Println("arr=", arr)
}
运行结果如下:
	arr= [1 2 3]
	arr= [100 2 3]
	arr= [100 200 3]
声明:《Go系列教程》为本站“54笨鸟”官方原创,由国家机构和地方版权局所签发的权威证书所保护。
 
	