数组+切片+map
-
-
数组定义:var a [len]int,比如:var a [6]int,长度一旦定义不能改变
-
长度是数组类型的一部分,因此,var a [5]int 和 var a [10]int 是不同的类型
-
数组可以通过下标进行访问,下标是从0 开始,最后一个元素的下标是len - 1
-
访问越界:如果下标在数组合法范围之外,则会触发访问越界,会panic
-
数组是值类型,因此改变副本的值,不会改变本身的值
arr2 := arr1 arr2[2] = 10 // 不会改变arr1
func test(arr [5]int) {
arr[0] = 1
}
func mian() {
var a [10]int
test(a) // error
}
因为数组是值类型,所以传到函数中是副本,因此要在函数中修改数组的值需要将数组的地址传入
func test(arr *[5]int) {
(*arr)[0] = 10
}
func main() {
var a [5]int
test(&a)
}
// part1
var arg0 [5]int = [5]int{1, 2, 3, 4, 5}
// part2
var arg1 = [5]int{1, 2, 3, 4, 5}
// part3
var arg2 = [...]int{1, 2, 3, 4, 5}
// part4
var str = [5]string{3: "hello world", 4: "tom"} // 0 1 2 是空的,稀疏数组
var age [5][3]int
var f [2][3]int = [...][3]int{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}
for index, v := range f { // 每一行
for index1, v1 := range v { // 每一列
// do some operation
}
}
-
-
切片的长度可以改变,因此,切片是一个可变的数组
-
切片遍历的方式和数组一样,可以用len()求长度
-
cap可以求出slice最大的容量,0 <= len(slice) <= cap(arry),其中arry是slice引用的数组
-
切片的定义:var 变量名 []类型,比如:var str []string、var arr []int
-
切片初始化:var slice []int = arr[start:end],包含start到end之间的元素,但是不包含end
-
var slice []int = arr[0:end] 可以简写成 var slice []int = arr[:end]
-
var slice []int = arr[start:len(arr)] 可以简写成 var slice []int = arr[start:]
-
var slice []int = arr[0:len(arr)] 可以简写成 var slice []int = arr[:]
-
如果切片要去掉最后一个元素,可以这样写 slice = slice[:len(slice) - 1]
var slice []type = make([]type, len) slice := make([]type, len) slice := make([]type, len, cap)
slice = append(slice, 10)
// 添加切片
var a = []int{1, 2, 3}
var b = []int{4, 5, 6}
a = append(a, b...)
var a [5]int = [...]int{1, 2, 3, 4, 5}
s := a[1:]
fmt.Printf("len[%d] cap[%d]\n", len(s), cap(s))
s[1] = 100
fmt.Println("before a:", a) // [1, 2, 100, 4, 5]
s = append(s, 10)
s = append(s, 10)
s = append(s, 10)
s = append(s, 10)
s = append(s, 10)
s = append(s, 10)
fmt.Println("before a:", a) // [1, 2, 100, 4, 5] a在slice容量超过前后没有变化,说明slice在内存不够的情况下会新开辟一片内存对数据进行存储
fmt.Printf("len[%d] cap[%d]\n", len(s), cap(s)) // 开辟后的内存是原来的两倍,即cap(s)是原来的两倍
s1 := []int{1, 2, 3, 4, 5}
s2 := make([]int, 10)
copy(s2, s1)
string底层是一个byte数组,因此,可以进行切片操作
str := "hello world" s1 := str[0:5] fmt.Println(s1) s2 := str[5:] fmt.Println(s2)
排序操作主要都在sort包中,导入就可以使用了
import("sort")
sort.Ints对整数进行排序,sort.Strings对字符串进行排序,sort.Float64s对浮点数进行排序
// 注意不能传入数组,因为数组是值类型的,要传切片,切片是引用类型的
var a = [5]int{1, 48, 5, 69, 21}
sort.Ints(a[:])
sort.SearchInts(a []int, b int) // 从数组a中查找b,前提是a必须有序
sort.SearchFloats(a []float64, b float64) // 从数组a中查找b,前提是a必须有序
sort.SearchStrings(a []string, b string) // 从数组a中查找b,前提是a必须有序
key-value的数据结构,又叫字典或关联数组
var map1 map[keyType]valueType // eg var a map[string]string var a1 map[string]int var a2 map[int]string var a3 map[string]map[string]string
注意:
声明是不会分配内存的,初始化需要make
// 使用make初始化
var a map[string]string
a = make(map[string]string, 10)
b := make(map[string]string, 10)
b["abc"] = "efg"
// 声明时初始化
var c map[string]int = map[string]int{
"a": 1,
"b": 2,
}
// 插入和更新
a["hello"] = "world"
// 查找
val, ok := a["hello"] // val是对应的value,ok存储的是是否有值,为bool类型
// 遍历
for k, v := range a {
fmt.Println(k, v)
}
// 删除
delete(a, "hello")
// 长度
len(a)

浙公网安备 33010602011771号