go语言基础—数组与slice
1、声明以及赋值
1、使用关键字var声明,或者简短声明
2、声明时,需要声明数组元素类型
3、若声明数组长度,则该长度也是数组类型的构成之一,如[3]int与[4]int是不同类型
4、若不声明数组长度,则是一个slice
5、未指定初始值的元素将用零值初始化
1.1 声明方式
// 关键字var
var x [num]int
// 简短声明
x := [num]int{1,2,3}
1.2 初始化赋值
// {}内直接写元素值
var a = [3]int{1,2,3}
// {}内按照键值对的方式,键为索引,值为元素值
var a = [100]int{99:-5,98:10} // 此时索引的顺序无关紧要
var a = [...]int{99:-5,98:10} // 等同上式,自动推导数组长度
var a = []int{99:-5,98:10} // 注意,这是定义slice,初始化的数据是slice的底层数据对象
1.3 运算、比较
// 数组之间只有同类型才能比较,运算,包括数据类型,数组长度都要相同
func main() {
// 数组之间只有同类型才能比较,运算,包括数据类型,数组长度都要相同
var a, b = [3]int{1, 2, 3}, [3]int{2, 3, 5}
// 只能通过下标获取单个元素进行运算,无法整体做运算
fmt.Println(a[0] + b[0])
// fmt.Println(a + b) // 报错
// 可以整体比较 == 判断是否包含完全相同的元素
fmt.Println(a==b)
}
/*
3
false
*/
2、slice
2.1 什么是slice
1、声明数组类型变量时,没有声明数组长度的就是slice
2、除此之外,由数组切片得到的结果也是slice
3、创建slice的内置方法:make
make([]Type, len)
make([]Type, len, cap) // same as make([]Type, cap)[:len]
/*
1、在底层make创建了一个匿名的数组变量,然后返回一个slice
2、只有通过返回的slice才能引用底层的数组变量
3、在第一种语句中,slice是整个数组的view
4、在第二个语句中,slice只引用了底层数组的前len个元素,但是容量将包含整个的数组。额外的元素是留给未来的增长用的
*/
2.2 slice的特点
1、slice只是对底层数据的引用,当引用的底层数组数据发生变化,slice也会发生同步变化
2、slice由三部分组成:指针,长度,容量
3、slice之间不能像数组一样通过==做比较
// 指针:指向第一个slice元素对应的底层数组元素的地址(不一定是第一个数组元素)
// 长度:slice中元素的个数,不能大于容量
// 容量:slice的指针在底层数组的位置开始到底层数组的结尾位置的长度
func main() {
var x = []int{88: 10}
fmt.Printf("长度len(x):%d\n容量cap(x):%d", len(x), cap(x))
x = x[2:3] // 变更slice的引用
fmt.Printf("\n长度len(x):%d\n容量cap(x):%d", len(x), cap(x))
}
/*
长度len(x):89
容量cap(x):89
长度len(x):1
容量cap(x):87
*/
2.3 比较
1、不能通过==的方式直接比较
2、对于字节型slice,可以使用标准库提供的高度优化的bytes.Equal函数
3、对于其他类型的slice,只能自己展开逐个元素比较
4、使用len(s)来判断slice是否为空,不要使用s==nil
// byte.Equal函数
func equal(x, y []string) bool {
if len(x) != len(y) {
return false
}
for i := range x {
if x[i] != y[i] {
return false
}
}
return true
}
2.4 追加slice元素
// slice在len小于cap的情况下,可以通过append方法向slice追加元素
var runes []rune
for _, r := range "Hello, 世界" {
runes = append(runes, r)
}
fmt.Printf("%q\n", runes) // "['H' 'e' 'l' 'l' 'o' ',' ' ' '世' '界']"

浙公网安备 33010602011771号