阅读《Go程序设计语言》:从Java的视角掌握Go(三)

本人在阅读《Go程序设计语言》时,通过比较Java和Go的不同来快速掌握Go语言,这是第三篇。

复合数据类型

复合数据类型:数组、slice、map和结构体;

数组和结构体的长度是固定的;

slice和map都是动态数据结构;

数组的声明和写法:

var a [3]int int[] a = new int[3];

var a [3]int = [3]int{1, 2, 3} int[] a = new int[]{1, 2, 3};

var a [3]int = […]int{1, 2, 3} int[] a = new int[]{1, 2, 3};

数组的长度是常量表达式,在编译时确定;

数组的遍历有索引;

例如定义一个100元素的数组:

r := […]int{99: -1}

数组元素类型可比较,那么数组也是可比较的。比较的是两边元素的值是否完全相同;

slice

slice没有指定长度,且不能用==来比较;

bytes.Equal

唯一的比较操作是nil比较;

make创建了一个无名数组并返回了它的一个slice,这个数组仅可以通过这个slice来访问;

slice底层----------

map

创建方式:

1
2
3
4
5
6
ages := make(map[string]int)
ages := map[string]int{
"alice": 31,
"cc": 34,
}

即使健不在map中,delete操作也是安全的;

使用给定的键来查找,如果对应的元素不存在,就返回值类型的零值;

不能获取map元素的地址,因为散列是不定的;

map的迭代顺序是不固定的;

设置元素之前,必须初始化map;

前面提到了总是有值,所以如果要判断是不是存在某个元素,可以使用:

1
if age, ok := ages["bob"]; !ok {}

map不可以比较,除了和nil;

结构体

用点号来访问活着通过指针访问;

指针用点号调用变量;

赋值表达式的左边无法识别一个变量;

结构体成员变量通常一行写一个,变量的名称在类型前面,但是相同类型的连续成员变量可以写在一行上;

结构体可以具有导出和不导出的成员变量;

聚合类型(包括数组)不可以包含他自己,但可以包含指向自己的指针;

结构体字面量:

1
2
type Point struct{x, y int}
p := Point{1, 2}

另一种:

1
anim := gitf.GIF{LoopCount: nframes}

简单的初始化方法:

1
2
3
4
pp := &Point{1, 2}
// 等价于下面的式子
pp := new(Point)
*pp = Point{1, 2}

结构体比较-------

可比较的结构体变量可以作为map的键;

如果结构体的所有成员变量都是可以比较的,那么这个结构体就是可以比较的;

结构体嵌套和匿名成员--------

结构体的匿名成员,不需要大量中间变量,但是没有快捷方式初始化结构体;

结构体字面量形状类型定义两种:尾部都必须,号;

JSON

小结

参考