引用数据类型:存储的是地址,地址指向的内存才是存储值的地方。
指针
指针类型以 *数据类型 的形式(包括用户自定义的类型)
例1:
var p *int
var a = 1
p = &a
例2:
var a = 1
p := &a
例3:
var n = [3]int{1, 2, 3}
var p *[3]int = &n
(*p)[1] = 3
例4:
type person struct {
name string
age int
}
pp := &person{"Tom", 18}
pp.age = 26
slice
切片其实是一个指向底层数组的一个数据类型([]T, T指切片内的数据类型)。
slice有三个属性
1.指针:指向底层数组(不一定指向底层数组的第一个元素)
2.长度:指slice的长度
3.容量:指指针指向底层数组的元素到底层数组最后一个元素的个数
len()用于获取数组或者切片的长度
cap()用于获取切片的容量
两中主要获得切片的方式
1.通过切割数组或者切片获得:s[i:j]指取>=i,<j的左闭右开区间。这样就有j-i个元素
i不写就默认取0值,j不写就默认取整个数组或者切片的长度。
例1:
var n = [...]int{1, 2, 3, 4, 5, 6}
m := n[:3] //[1 2 3]
m1 := n[2:] //[3 4 5 6]
m2 := n[:] //[1 2 3 4 5 6]
2.直接定义:
例1:
var n = []int{1, 2, 3} //定义了一个长度和容量相等
//指针指向底层数组第一个元素的切片
var n1 = make([]int, 3, 4)//3代表切片长度,4代表容量
//4不写就默认和长度相等
slice和数组最直观的区别就在于slice是可扩容的。
如果长度超出了容量,就新创建一个底层数组将之前的数据复制过去。
Go提供了append函数给slice扩容
例1:
var x []int //这样声明并不会分配内存
x = append(x, 1)
x = append(x, 1, 2, 3)
x = append(x, x...) //追加x中的所有元素
slice的遍历
var x = []int{1, 2, 3, 4, 5}
for i, j := range x {
}//i是下标,j是对应的值。如果不使用下标可以用_代替j
map
map 是 key-value 数据结构,又称为字段或者关联数组。
map的类型为map[keyType]valueType
map中key与value是一一映射的。
声明举例
例1:
var a map[string]string
b := map[int]string{
1: "tom",
2: "lisa",
}
c := make(map[string]string, 3)
a["no1"] = "Tom"
a["no2"] = "Lisa"
a["no3"] = "Jack"
map也是可以动态扩容的。
例1:
m := make(map[int]string, 1)
m[1] = "tom"
m[2] = "lisa"
删除map中的映射
例1:
m := make(map[int]string, 1)
m[1] = "tom"
delete(map, 1)
map的查找
例1:
m := make(map[int]string, 1)
m[1] = "tom"
m[2] = "lisa"
val, ok := m[1]
map的遍历
m := make(map[int]string, 1)
m[1] = "tom"
m[2] = "lisa"
for key, val := range m {
}
通道,接口也是引用类型,这里就不介绍了。