Go语言中数组是具有固定长度的相同数据类型元素的序列。而slice的长度可变。个人理解,类似C++中数组和vector的区别。
1. 数组
1.1 初始化
var a1 [3]int //3个整数型的数组,初始值是3个0
a2 := [5]int{1,2,3} //长度为5,后两位是0
var a3 = [...]int{6, 7, 8} //不声明长度
a4 := [...] int {1,2,3} //不声明长度
a5 := [...] int {3:1} //长度为3的数组,只有最后一个是1,其他都是0
总之,初始化方式有四种,二二组合:是否指定长度X初始化部分、全部元素。
1.2 类型
package main
import (
"fmt"
"reflect"
)
func main() {
s1 := [5]int{1, 2, 3} // 这么写就是数组类型,后两位是0
fmt.Println("type:", reflect.TypeOf(s2))
}
结果:
type: [5]int
可以看到[5]int是一个完整的类型。[4]int和[5]int是不同的类型。
1.3 参数传递
数组长度是类型的一部分,因此,函数声明时变量类型里数组长度是不可缺少的。数组的传递是值传递的。在被调用函数内部修改数组,不影响调用方的数组的值。
package main
import "fmt"
func modify_slice(s [5]int) {
s[0] = 10
fmt.Println("In modify_slice, slice values is:", s)
}
func main() {
s := [5]int{1,2,3,4,5}
modify_slice(s)
fmt.Println("In main, slice values is:",s)
}
输出:
In modify_slice, slice values is: [10 2 3 4 5]
In main, slice values is: [1 2 3 4 5]
2. slice
2.1 初始化
slice的初始化,可以通过截取数组或slice,或者使用make。
s1 := []int{1, 2, 3} //在内存中构建一个包括有3个元素的数组,然后将这个数组的引用赋值给s这个Slice
a := [5]int{1, 2, 3, 4, 5} //a是数组
s2 := a[1:4] //从数组中切片构建Slice
s3 := make([]int, 10, 20) //make函数初始化,len=10,cap=20
2.2 类型
package main
import (
"fmt"
"reflect"
)
func main() {
s2 := []int{1, 2, 3}
fmt.Println("type:", reflect.TypeOf(s2))
}
输出:
type: []int
2.3 参数传递
slice的参数传递是引用传递,在被调用函数修改元素的值,同时也是在修改调用方的slice的元素。
package main
import "fmt"
func modify_slice(s []int) {
s[0] = 10
fmt.Println("In modify_slice, slice values is:", s)
}
func main() {
s := []int{1,2,3,4,5}
modify_slice(s)
fmt.Println("In main, slice values is:",s)
}
输出:
In modify_slice, slice values is: [10 2 3 4 5]
In main, slice values is: [10 2 3 4 5]
2.3 slice的len和cap
在追加元素时,如果容量cap不足时,cap一般变为原来的2倍来实现扩容
2.4 用slice截取数组
用slice截取数组时,修改slice会影响到数组。因为slice就是对原数组某一段的引用。
package main
import (
"fmt"
)
func main() {
a := [6]int{1, 2, 3, 4, 5}
s := a[1:3]
fmt.Println("before, arr is:", a)
s[1] = 10
fmt.Println("after, arr is:", a)
}
输出:
before, arr is: [1 2 3 4 5 0]
after, arr is: [1 2 10 4 5 0]