在Golang中,数组属于聚合类型,而切片属于引用类型。其实切片的底层逻辑就是用数组实现的,所以我们首先需要了解数组。
一、数组 Array
数组是具有相同唯一类型的一组已编号且长度固定的数据项序列,这种类型可以是任意的原始类型例如整型、字符串或者自定义类型。
相对于去声明 number0, number1, ..., number99 的变量,使用数组形式 numbers[0], numbers[1] ..., numbers[99] 更加方便且易于扩展。
数组元素可以通过索引(位置)来读取(或者修改),索引从 0 开始,第一个元素索引为 0,第二个索引为 1,以此类推。
数组初始化
1、直接赋值
var balance = [5]float32{1000.0, 2.0, 3.4, 7.0, 50.0}//等价于
balance := [5]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
2、不确定数组长度时
var balance = [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0}//等价于
balance := [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
3、指定位置初始化,其余位置补0
// 将索引为 1 和 3 的元素初始化
balance := [5]float32{1:2.0,3:7.0}
二、切片 Slice
Go 数组的长度不可改变,在特定场景中这样的集合就不太适用,Go 中提供了一种灵活,功能强悍的内置类型切片("动态数组"),与数组相比切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大。
切片初始化
s := [] int {1,2,3 } //直接初始化切片,[] 表示是切片类型,{1,2,3} 初始化值依次是 1,2,3。cap=len=3。
s := arr[:] //初始化切片 s,是数组 arr 的引用。
s := arr[startIndex:endIndex] //将 arr 中从下标 startIndex 到 endIndex-1 下的元素创建为一个新的切片。
s := arr[startIndex:] //缺省 endIndex 时将表示一直到 arr 的最后一个元素。
s := arr[:endIndex] //缺省 startIndex 时将表示从 arr 的第一个元素开始。
s := s[startIndex:endIndex] //通过切片 s 初始化切片 s1
s := make([]type, len)//通过内置函数 make() 初始化切片 s,[]int 标识为其元素类型为 int 的切片,length为长度
s := make([]int,length,capacity) //length为长度,capacity为容量
len() 和 cap() 函数
切片是可索引的,并且可以由 len() 方法获取长度。切片提供了计算容量的方法 cap() 可以测量切片最长可以达到多少。
package main
import "fmt"
func main() {
var numbers = make([]int,3,5)
printSlice(numbers)
}
func printSlice(x []int){
fmt.Printf("len=%d cap=%d slice=%v\n",len(x),cap(x),x)
//输出 len=3 cap=5 slice=[0 0 0]
}
append()函数
s := make([]int, 5)
s = append(s, 6, 7)
fmt.Println(len(s), cap(s)) // 输出7 10
s = append(s, 8, 9, 10, 11)
fmt.Println(len(s), cap(s))//输出11 20
s5 := make([]int, 5)
s6 := []int{11, 22, 33, 44, 55, 66}
s := append(s5, s6...)
fmt.Println(s, len(s), cap(s))//输出[0 0 0 0 0 11 22 33 44 55 66] 11 12
总结
array和slice有以下区别
1、初始化方式
2、array定长,slice动态变化长度
3、当切片和数组作为参数在函数(func)中传递时,数组传递的是值,而切片传递的是指针。因此当传入的切片在函数中被改变时,函数外的切片也会同时改变。相同的情况,函数外的数组则不会发生任何变化。当切片和数组作为参数在函数(func)中传递时,数组传递的是值,而切片传递的是指针。因此当传入的切片在函数中被改变时,函数外的切片也会同时改变。相同的情况,函数外的数组则不会发生任何变化。