复杂数据类型:数组,切片(slice),map,结构体
1.数组
数组是具有固定长度且拥有零个或多个相同数据类型元素的序列
Go语言中的数组和python中的数组最大的不同,这里的数组是固定长度的,定义后不能再插入和修改数据,使用的次数较少,较多是使用是切片(slice)
例子:1
2
3
4
5
6var a [3]int //定义一个整型数组
b := [3]int{1, 2, 3} //定义一个长度为3的整型数组,并赋值
c := b[0] //取值
fmt.Println(a)
fmt.Println(b)
fmt.Println(c)
输出:
[0 0 0]
[1 2 3]
1
注意:数组的长度是数组类型的一部分,所以[3]int和[4]int是两种不同的数组类型。整型未赋值的为零,字符串未赋值的为空。
2.切片(slice)
切片的底层也是数组,但可以变长。定义时,程序会去申请一个大于这个切片的数组来存储切片,如果切片新增数据,先去检测切片是否有空间去存储,如果没有,程序再去申请一个更长的数组来存储这个切片,每次申请的数组的长度Go有一个较为复杂的算法来实现高效。
例子:1
2
3
4
5
6
7
8
9
10a := []int{1, 2, 3, 4, 5, 6} //定义一个切片
b := a[1:] //取a中的第二个值到最后
c := b[2:3] //取第三个值,但不包括第四个值
e := make([]int, 5) //使用make函数定义一个长度为5的切片
a = append(a, 7) //使用内置append函数插入新的值
a = append(a[:2], a[3:]...) //删除元素(第三个元素)
fmt.Println(a)
fmt.Println(b)
fmt.Println(c)
fmt.Println(e)
输出:
[1 2 4 5 6 7]
[2 3 4 5 6]
[4]
[0 0 0 0 0]
3.map
map是拥有键值对的无序集合。所有的键的类型必须相同,所有的值的类型必须相同,但键的类型和值的类型不一定相同
例子:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17a := make(map[string]int) //定义一个map
a["test"] = 1 //赋值
//定义一个map,并赋值
b := map[string]string{
"1": "a",
"2": "b",
}
fmt.Println(a)
fmt.Println(b)
//遍历map
for k, v := range b {
fmt.Printf("key is %s,value is %s\n", k, v)
}
//判断键是否存在,如果存在ok为true,如果不存在ok为false
if _, ok := b["3"]; !ok {
fmt.Println("b中不存在此键!")
}
输出:
map[test:1]
map[1:a 2:b]
key is 1,value is a
key is 2,value is b
b中不存在此键!
4.结构体
结构体是零个或多个任意类型的命名变量组成的一种聚合数据类型1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16//定义一个结构体,可以用来存储用户的信息
type user struct {
id int
name string
age int
height int
}
//初始一个结构体并赋值
user1 := user{1, "test", 18, 170}
//下面的等同于上面的,初始一个结构体,再分别赋值结
var user2 user
user2.id = 2
user2.name = "test2"
user2.age = 20
fmt.Println(user1)
fmt.Println(user2)
输出:
{1 test 18 170}
{2 test2 20 0}
初始赋值还有下面的方法
user3 := user1{name:”test3”,id:3} //可以打乱结构体内的变量顺序
和
user3 := user{3,”test3”,18,178}这两种初始化方式不能混用
结构体中可以包含另一个结构体
结构体内不能包含自己,但可以包含指向自己的结构体指针,用于链表等
如果结构体内的每个变量都是可以比较的,那这个结构体就是可比较的