版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/chao2016/article/details/81537007
内建容器有数组和Map
这里讲三个概念:数组、切片、Map
1. 数组
数组是值类型
- [10]int和[20]int是不同的类型
- 调用func f(arr [10]int)会拷贝数组。想改变原数组的值,用指针类型参数
- golang一般不直接使用数组
arrays.go:
package main
import "fmt"
func printArray(arr *[5]int) {
arr[0] = 100
for i, v := range arr {
fmt.Println(i, v)
}
}
func main() {
var arr1 [5]int
arr2 := [3]int{1, 3, 5}
arr3 := [...]int{2, 4, 6, 8, 10}
var grid [4][5]int // 多维数组,4个长度为5的int数组
// 打印数组
fmt.Println(arr1, arr2, arr3)
fmt.Println(grid)
// 遍历数组
for i:= 0; i < len(arr3); i++ {
fmt.Print(arr3[i])
}
fmt.Println()
// 遍历数组可以用range关键字
// 获得下标
for i := range arr3 {
fmt.Print(arr3[i])
}
fmt.Println()
// 获得值
for _, v := range arr3 {
fmt.Print(v)
}
fmt.Println()
// 获得数组下标和值
for i, v := range arr3 {
fmt.Println(i, v)
}
fmt.Println("printArray(arr1):")
printArray(&arr1)
fmt.Println("printArray(arr3):")
printArray(&arr3)
fmt.Println("arr1 and arr3:")
fmt.Println(arr1, arr3)
}
输出:
[0 0 0 0 0] [1 3 5] [2 4 6 8 10]
[[0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0] [0 0 0 0 0]]
246810
246810
246810
0 2
1 4
2 6
3 8
4 10
printArray(arr1):
0 100
1 0
2 0
3 0
4 0
printArray(arr3):
0 100
1 4
2 6
3 8
4 10
arr1 and arr3:
[100 0 0 0 0] [100 4 6 8 10]
2. 切片(Slice)
2.1 slices.go:
package main
import "fmt"
func updateSlice(s []int) {
s[0] = 100
}
func main() {
arr := [...]int{0, 1, 2, 3, 4, 5, 6, 7}
fmt.Println("arr[2:6] =", arr[2:6])
fmt.Println("arr[:6] =", arr[:6])
s1 := arr[2:]
fmt.Println("arr[2:] =", s1)
s2 := arr[:]
fmt.Println("arr[:] =", s2)
fmt.Println()
fmt.Println("After updateSlice(s1):")
updateSlice(s1)
fmt.Println(s1)
fmt.Println(arr)
fmt.Println()
fmt.Println("After updateSlice(s2):")
updateSlice(s2)
fmt.Println(s2)
fmt.Println(arr)
fmt.Println()
fmt.Println("Reslice:")
fmt.Println(s2)
s2 = s2[:5]
fmt.Println(s2)
s2 = s2[2:]
fmt.Println(s2)
fmt.Println("Extending slice")
arr[0], arr[2] = 0, 2
s1 = arr[2:6]
s2 = s1[3:5] // 取的[s1[3], s1[4]]
//fmt.Println(s1[4]) // 会报错
fmt.Println("s1 =", s1)
fmt.Println("s2 =", s2)
fmt.Println()
// slice可以向后扩展,不可以向前扩展
// s[i]不可以超越len(s),向后扩展不可以超越底层数组cap(s)
fmt.Println("arr =", arr)
fmt.Printf("s1 = %v, len(s1) = %d, cap(s1) = %d\n",
s1, len(s1), cap(s1))
fmt.Printf("s2 = %v, len(s2) = %d, cap(s2) = %d\n",
s2, len(s2), cap(s2))
fmt.Println()
s3 := append(s2, 10)
s4 := append(s3, 11)
s5 := append(s4, 12)
fmt.Println("s3, s4, s5 =", s3, s4, s5)
// s4和s5不再是arr的view
// 添加元素时如果超越cap,系统会重新分配更大的底层数组
fmt.Println("arr =", arr)
}
输出:
arr[2:6] = [2 3 4 5]
arr[:6] = [0 1 2 3 4 5]
arr[2:] = [2 3 4 5 6 7]
arr[:] = [0 1 2 3 4 5 6 7]
After updateSlice(s1):
[100 3 4 5 6 7]
[0 1 100 3 4 5 6 7]
After updateSlice(s2):
[100 1 100 3 4 5 6 7]
[100 1 100 3 4 5 6 7]
Reslice:
[100 1 100 3 4 5 6 7]
[100 1 100 3 4]
[100 3 4]
Extending slice
s1 = [2 3 4 5]
s2 = [5 6]
arr = [0 1 2 3 4 5 6 7]
s1 = [2 3 4 5], len(s1) = 4, cap(s1) = 6
s2 = [5 6], len(s2) = 2, cap(s2) = 3
s3, s4, s5 = [5 6 10] [5 6 10 11] [5 6 10 11 12]
arr = [0 1 2 3 4 5 6 10]
2.2 sliceops.go:
package main
import "fmt"
func printSlice(s []int) {
fmt.Printf("%v\n len=%d, cap=%d\n", s, len(s), cap(s))
}
func main() {
fmt.Println("Creating slice:")
var s []int // Zero value for slice is nil
for i := 0; i < 100; i++ {
s = append(s, 2*i+1)
}
fmt.Println(s)
s1 := []int{2, 4, 6, 8}
printSlice(s1)
s2 := make([]int, 16)
printSlice(s2)
s3 := make([]int, 10, 32)
printSlice(s3)
fmt.Println("Copying slice:")
copy(s2, s1)
printSlice(s2)
fmt.Println("Deleting elements from slice:")
s2 = append(s2[:3], s2[4:]...)
printSlice(s2)
fmt.Println("Popping from front:")
front := s2[0]
s2 = s2[1:]
fmt.Println(front)
printSlice(s2)
fmt.Println("Popping from back:")
tail := s2[len(s2) - 1]
s2 = s2[:len(s2) - 1]
fmt.Println(tail)
printSlice(s2)
}
输出:
Creating slice:
[1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43 45 47 49 51 53 55 57 59 61 63 65 67 69 71 73 75 77 79 81 83 85 87 89 91 93 95 97 99]
[2 4 6 8]
len=4, cap=4
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
len=16, cap=16
[0 0 0 0 0 0 0 0 0 0]
len=10, cap=32
Copying slice:
[2 4 6 8 0 0 0 0 0 0 0 0 0 0 0 0]
len=16, cap=16
Deleting elements from slice:
[2 4 6 0 0 0 0 0 0 0 0 0 0 0 0]
len=15, cap=16
Popping from front:
2
[4 6 0 0 0 0 0 0 0 0 0 0 0 0]
len=14, cap=15
Popping from back:
0
[4 6 0 0 0 0 0 0 0 0 0 0 0]
len=13, cap=15
3. Map
map的操作:
- 创建:make(map[string]int)
- 获取元素:m[key]
- key不存在时,获得Value类型的初始值
- 用value, ok:=m[key]来判断是否存在key
- 用delete删除一个key
- 使用len获得元素个数
map的遍历:
- 用range遍历key,或者遍历key-value对
- 不保证遍历顺利,如需顺序,需手动对key排序
map的key:
- map使用哈希表,必须可以比较相等
- 除了slice,map,function的内建类型都可以作为key
- Struct类型不包含上述三个字段,也可作为key
maps.go:
package main
import "fmt"
// map的操作
// 1. 创建:make(map[string]int)
// 2. 获取元素:m[key]
// 3. key不存在时,获得Value类型的初始值
// 4. 用value, ok:=m[key]来判断是否存在key
// 5. 用delete删除一个key
// 6. 使用len获得元素个数
// map的遍历
// 1. 用range遍历key,或者遍历key-value对
// 2. 不保证遍历顺利,如需顺序,需手动对key排序
// map的key
// 1. map使用哈希表,必须可以比较相等
// 2. 除了slice,map,function的内建类型都可以作为key
// 3. Struct类型不包含上述三个字段,也可作为key
func main() {
fmt.Println("Creating map:")
m := map[string]string {
"name": "chao",
"course": "golang",
"site": "aliyun",
"qualicty": "notbad",
}
m2 := make(map[string]int) // m2 == empty map
var m3 map[string]int // m3 == nil,go的nil与其他语言的None不同,它可以进行计算
fmt.Println(m)
fmt.Println(m2)
fmt.Println(m3)
fmt.Println()
// hashmap,key值是无序的
fmt.Println("Traversing map:")
for k, v := range m {
fmt.Println(k, v)
}
fmt.Println()
fmt.Println("Getting values:")
courseName := m["course"]
fmt.Println(courseName)
causeName, ok := m["cause"]
fmt.Println(causeName, ok) // key不存在时,获得Value类型的初始值
if causeName, ok = m["cause"]; ok {
fmt.Println(causeName)
} else {
fmt.Println("key does not exist")
}
fmt.Println()
fmt.Println("Deleting values:")
name, ok := m["name"]
fmt.Println(name, ok)
delete(m, "name")
name, ok = m["name"]
fmt.Println(name, ok)
}
输出:
Creating map:
map[name:chao course:golang site:aliyun qualicty:notbad]
map[]
map[]
Traversing map:
name chao
course golang
site aliyun
qualicty notbad
Getting values:
golang
false
key does not exist
Deleting values:
chao true
false
有疑问加站长微信联系(非本文作者)