数组+切片+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)