目录
本章讲解4种复合数据类型:数组、slice、map和struct
其中,数组和struct长度固定,slice和map是动态数据结构。
4.1 数组
数组长度固定,除特殊情况,很少使用。尽量用slice。
4.2 slice
能用类型:[] T
类似C++中的vector
slice有三个属性:底层数组指针、长度和容量。
两种创建方式:字面值常量和make。
//1. 字面值常量
test1 := []int {11, 22, 33}
fmt.Printf("len=%d, cap=%d\n", len(test1), cap(test1))//len=3, cap=3
test1 = append(test1, 44)
fmt.Printf("len=%d, cap=%d\n", len(test1), cap(test1))//len=4, cap=6
test0 := []int {9:88}//长度是10,第10个元素初始化为88,其它初始化0
fmt.Printf("len=%d, cap=%d\n", len(test0), cap(test0))//len=10, cap=10
//2. make
test2 := make([]int, 3)//len=3, cap=3
test3 := make([]int, 3, 5)//len=3, cap=5
slice唯一允许的比较操作是和nil比较。如: if s == nil { /* */}
slice类型的零值是nil。此时表示没有对应的底层数组。检查一个slice是否为空,用len(s) == 0,而不是s == nil。
创建空slice
1. s := make([]int, 0)
2. s := []int{}
3. var s []int
4.2.1 append函数
append可以往slice中追加值。如:
name := []string{}
name = append(name, "zdchu")
name = append(name, ", hello")
往一个slice后面追加另一个slice:
func main() {
seq := []string {"11", "12", "13", "14", "15"}
seq2 := []string {"21", "22", "23", "24", "25"}
seq = append(seq, seq2[:]...)//...表示把seq2[:]中的元素一个一个的追加
fmt.Println(seq)
}
append增长机制类似C++中vector。
利用append删除元素:
删除单个元素:
seq := []string{"a", "b", "c", "d", "e"}
index := 2 //指定删除位置
//将删除点前后的元素连接起来
seq = append(seq[:index], seq[index+1:]...)
fmt.Println(seq)//[a b d e]
如果第二个参数是slice,那么要用...,这样就会把第二个slice中的元素一个一个的追加到第一个slice中
批量删除:
func main() {
seq := []string{"a", "b", "c", "d", "e"}
// 指定删除位置
index := 3
// 将删除点前后的元素连接起来
seq = append(seq[:0], seq[index+1:]...)
fmt.Println(seq)//[e]
}
4.2.2 slice就地修改
删除字符串中空字符串:
func main() {
data := []string {"aaa", "", "ccc"}
fmt.Println(nonempty(data))//[aaa ccc]
fmt.Println(data)//[aaa ccc ccc]
}
func nonempty(strings []string) []string {
out := strings[:0]//引用原始slice,输入与输出slice拥有相同的底层数组
for _, s := range strings {
if s != "" {
out = append(out, s)
}
}
return out
}
删除slice中指定位置的元素:
func main() {
data := []int {10,20,30,40,50}
d := remove(data, 2)
fmt.Println(d)//[10 20 40 50]
fmt.Println(data)//[10 20 40 50 50]
}
//在乎元素顺序
func remove(s []int, i int) []int {
copy(s[i:], s[i+1:])
return s[:len(s)-1]
}
//不在乎元素顺序
func remove(s []int, i int) []int {
s[i] = s[len(s)-1]
return s[:len(s)-1]
}
4.3 map
通用类型:map[K]V
创建及添加:
//1. make方式
myMap := make(map[string]int)
myMap["aa"] = 1
myMap["bb"] = 2
fmt.Println(myMap)//map[aa:1 bb:2]
//2. 字面值
yourMap := map[string]int{}
fmt.Println(yourMap)//map[]
otherMap := map[string]int {"A":1, "B":2}
fmt.Println(otherMap)//map[A:1 B:2]
删除:内置函数delete,用法:delete(map, K),举例:delete(myMap, "aa")
遍历:for k,v := range myMap {}
判断key是否存在:
if age, ok := ages["zdchu"]; !ok {
//zdchu这个Key不在map ages中
}
4.4 struct
type Employee struct {
ID int
Name, Address string
Salary int
}
出于效率考虑,大型的结构体通常用结构体指针的方式传递给函数。
4.4.1 struct字面量
todo
4.4.2 struct比较
todo
4.4.3 struct嵌套和匿名成员
todo
4.5 JSON
todo
4.6 文本和HTML模板
todo