今天主要介绍一下golang特有的几种复合数据类型
struct结构体,就相当于java中的一个实体类,里面只可以定义一些属性,没有方法的定义,下面就是一个user的结构体的定义,由 struct 关键字开头,后面跟着用一对大括号 {} ,其中包裹着的一系列字段(field)声明
type User struct {
name string
email string
}
下面是我们如何去实例化一个结构体对象
user1 := User{"张三", "zhangsan@126.com"}
// 使用带字段名的组合字面量来表示结构体值
user2 = User{name: "李四", email: "lisi@126.com"}
// name和email字段的值都为空字符串""
user3 = User{}
// 使用选择器来访问和修改字段值。
var user4 User // 等价于 user4 := User{}
user4.name = "王五"
user4.email = "wangwu@126.com"
fmt.Println(user4.name) // 王五
下面说一下切片,java中没有这种数据结构的概念,切片的定义和数组有些类似,类似动态数组,可以按需自动增长和缩小
下面是创建切片的几种方式
切片的底层数据结构,是由一个指针,长度,容量三个字段组成的,底层的数组一般是没法直接访问的,即使通过数组创建的切片,再通过扩容以后也可能不是同一个数组了。
下面看一个切片扩容的例子,切片通过append添加一个元素以后,返回的新切片的数组与原切片的数组已经不是同一个数组了,由于原数组的长度已经满了,添加新元素以后需要对数组扩容,这就扩容一倍生成了一个新数组,把原数组的值拷贝一份到新数组。一旦元素个数超过 1000,容量的增长因子会设为 1.25,也就是会每次增加 25%的容量
下面说一下map,下面是几种创建的方式,map需要初始化以后才能使用,下面的例子中只声明一个map,直接使用的化会抛出异常
// 通过make创建一个映射,键的类型是 string,值的类型是 int
dict1 := make(map[string]int)
// 直接赋值创建一个映射
dict2 := map[string]string{“Red”: “#da1337”, “Orange”: “#e95a22”}
// 通过声明映射创建一个映射,这种称为nil映射,不能直接进行操作
var colors map[string]string
// 将 Red 的代码加入到映射,会出现异常
colors[“Red”] = “#da1337”
Runtime Error:
panic: runtime error: assignment to entry in nil map
下面的是go中map的底层数据结构,和java中的map还是有些差异的,和1.7版本的ConcurrentHasMap还有些类似,先是分成几个桶, 每个bucket 存储8个key和value, 如果超过就重新创建一个bucket挂载在原bucket上,持续挂接形成链表。
先通过低位的散列值确定所在桶的位置,再通过高位的散列值确定桶里元素的位置。