数组
基本格式
var identifier [count]type
声明和初始化
var a [3]int
var b [3]int = [3]int{1, 2, 3}
c := [...]int{1, 2, 3}
d := [5]int{10} //只初始化前面的元素
e := [5]int{0: 2, 3: 5} //初始化第0个元素为2,第3个元素为5
注意,数组长度是数组的一部分,[3]int
和[5]int
不是同一个类型,不能赋值
a := [3]int{10}
var b [5]int
b = a //非法
数组的长度也是用len()
来取,所以遍历可以写作
for i := 0; i < len(a); i++{
}
也可以用range遍历
for index, value := range a {
fmt.Println(index, value)
}
数组是值类型
切片
切片是基于数组类型做的一层封装。
基本格式
var indentifier [] type
基于数组声明
a := [5]int{1, 2, 3, 4, 5}
b := a[1:4]
c := []int{1, 2, 3}
切片的操作
格式 | 意义 |
---|---|
arr[start:end] |
从start开始到end-1的所有元素 |
a[start:] |
从start开始到结束的所有元素 |
a[:end] |
从开始到end-1的所有元素 |
a[:] |
所有元素 |
注意,切片是引用,能够通过切片修改数组的值
通过make创建,使用len()
求长度,使用cap()
求容量。长度超过容量会进行扩容,容量翻倍。类似于StringBuilder。
a := make([]int, 5, 10) //make(type, currentCount, maxCount)
注意,扩容后内存地址会改变。所以如果切片是用来对数组进行更改的,不要随意的append,一旦扩容,内存地址改变,就不能更改到你想更改的数组了。
切片的追加
var a []int
a = append(a, 10) //追加单个元素
b := []int{1, 2, 3}
a = append(a, b...) //追加一个切片
切片的拷贝。拷贝不会进行扩容,只会做填充。所以长度不等时,会忽略差值。
a := [...]int{1, 2, 3, 4, 5, 6}
b := a[1:3]
c := a[2:4]
copy(b, c)
make和new的区别
make
为内建类型slice
、map
和channel
分配内存。(只有这三种)
new
用于各种类型的内存分配,new返回的是一个指针。
map
map是引用类型
基本格式
var identifier map[keyType]valueType
声明和初始化
var a map[string]int
a = make(map[string]int, 10)
b := map[string]int{
"666":666,
}
判断key是否存在
value, ok := a["666"]
if ok {
fmt.Println("key 666 exist, value is ", value)
}
删除元素
delete(a,key)