上QQ阅读APP看书,第一时间看更新
3.2.2 非引用类型和引用类型
1.数组
每种语言里面都有数组,数组是一系列“同一类型数据”的集合,它由两部分组成:数组元素和长度。数组中包含的数据称为数组元素,包含的元素个数则称为数组的长度。下面的示例中展示了一个长度为5、元素类型为int、元素值为“0、1、2、3、4”的数组。
numbers := [5]int{0, 1, 2, 3, 4}
2.切片
数组的长度在定义后是无法修改的。数组是值类型,每次传递都会产生一份副本,这无疑会增加内存开销。切片(slice)的诞生弥补了数组的不足。初看起来,切片就像一个指向数组的指针,实际上它底层的数据结构由以下三部分组成。
● 指向原生数组的指针。
● 数组切片中的元素个数。
● 分配给数组切片的存储空间。
切片的示例如下。
slice := []byte("Hello")
3.映射
映射是一种无序的键值对集合,通过散列表来实现。映射最重要的特点是可以通过键快速检索数据。键类似于数据库中的唯一索引,它指向数据的值。映射相关的示例如下。
m := map[string]int{"one": 1, "two": 2, "three": 3}
m1 := map[string]int{}
m1["one"] = 1
m2 := make(map[string]int, 10)
4.指针
每个变量都会占据一块内存空间,每个内存空间都有其地址。指针用于指向内存地址,指针类型变量的值则指向某个值的内存地址。指针的示例如下。
var ptrA *int
fmt.Println(&ptrA)
5.通道
通道是基于Go语言的设计模型CSP诞生的。在并发场景中,协程通过通信来共享内存。通道是并发安全的数据类型,通道的示例如下。
ch := make(chan int, 2)
ch <- 1
ch <- 2
6.接口
接口被用来描述行为。接口包含一系列定义的行为(方法),但不直接实现这些行为(方法),它们是由自定义类型(如结构体)实现的。我们设定T表示类型,I表示接口,t表示类型的值。如果类型T实现了接口I中包含的方法集的所有方法,则可以将此类型的值t(可以理解为类型为T,它的实例为t)赋予这个接口I。接口相关的示例如下。
type Duck interface {
Swim()
Walk()
}
7.函数
函数除了具有我们所熟知的功能,还可以作为类型存在。函数的示例如下。
myfunc := func() bool {
return x > 100
}