make 用来初始化内置引用类型,必须用于 slice、map、chan 的创建和初始化。
package main import "fmt" // 数组都是固定长度 // 类型是"[10]int" 其中包含了长度 var array1 [10]int // 长度需要是定值 按值传递 func array_func1(a [10]int) {} // 长度需要是定值 可以传递指针 func array_func2(pa *[10]int) {} func main() { array1[0] = 9 array1[9] = 0 // 自动推断长度(如果不用"..."就是切片) array2 := [...]int{1, 2, 3} fmt.Println(array2) // 使用 index: value 的方式初始化 // 自动推断的结果是:长度为5 array3 := [...]int{4: -1} fmt.Println(len(array3), array3) array_func1(array1) array_func2(&array1) }
package main import "fmt" // 一个slice类型一般写作 []T // slice的语法和数组很像,只是没有固定长度而已 // slice是对某一个底层数组的引用 var array [5]int = [5]int{0, 1, 2, 3, 4} func main() { // 从一个数组创建一个切片 // 切片会绑定这个数组 // 对切片的修改会反映到原始数组 s1 := array[0:3] // [0, 3) fmt.Println(array) fmt.Println(s1) // 尝试向切片中添加数据(切片是可以一直拓展的) // 当数据长度超过原始的数组后 // 切片和原始数组就会解除绑定,转为绑定一个新的容量足够的匿名数组(类似std::vector) for i := 0; i < 50; i++ { s1 = append(s1, -1) } fmt.Println(array) fmt.Println(s1) // 以初始值的形式创建一个切片 起始就是绑定一个匿名数组 s2 := []int{9, 8, 7} fmt.Println(s2) // 手动创建一个切片 可以制定其len 和 cap // len 表示切片长度 cap表示匿名数组的长度(也就是为切片预留的数据空间) // 当超出 cap 的空间之后 Go会重新分配一个新的足够长的(一般是2倍长度)匿名数组 将数据拷贝过去 s3 := make([]int, 1, 100) fmt.Println(s3) }
package main import "fmt" func main() { // 只是声明了变量 但是没有实际创建map var ages map[string]int fmt.Println(ages == nil) // "true" fmt.Println(len(ages) == 0) // "true" 虽然是 nil 但是可以进行一些基础操作 // 创建map ages = make(map[string]int) ages["bob"] += 1 // 如果没有这个key 会返回0 // 删除一个key 即使这个key不存在也没关系 delete(ages, "anny") // 获取value的时候 一并获取这个key是否存在 if age, ok := ages["sam"]; ok { fmt.Println("sam's age is", age) } else { fmt.Println("There is no sam") } // 遍历map for name, age := range ages { fmt.Println(name, age) } // 复合map g := make(map[int]map[int]bool) g[0] = make(map[int]bool) g[0][0] = true }
package main import "fmt" func main() { // Go没有原生的Set 可以使用map[T]bool 代替 set<T> // 更节省空间的做法是:用struct{}代替bool s := make(map[int]struct{}) s[1] = struct{}{} if _, exists := s[1]; exists { fmt.Println("1 exists") } delete(s, 2) for key := range s { fmt.Println(key) } }