第12条 使用复合字面值作为初值构造器

在上一条中,我们了解到零值可用对于编写出符合Go惯用法的代码是大有裨益的。但有些时候,零值并非最好的选择,我们有必要为变量赋予适当的初值以保证其后续以正确的状态参与业务流程计算,尤其是Go语言中的一些复合类型的变量。

Go语言中的复合类型包括结构体、数组、切片和map。对于复合类型变量,最常见的值构造方式就是对其内部元素进行逐个赋值,比如:

var s myStruct
s.name = "tony"
s.age = 23

var a [5]int
a[0] = 13
a[1] = 14
...
a[4] = 17

sl := make([]int, 5, 5)
sl[0] = 23
sl[1] = 24
...
sl[4] = 27

m := make(map[int]string)
m[1] = "hello"
m[2] = "gopher"
m[3] = "!"

但这样的值构造方式让代码显得有些烦琐,尤其是在构造组成较为复杂的复合类型变量的初值时。Go提供的复合字面值(composite literal)语法可以作为复合类型变量的初值构造器。上述代码可以使用复合字面值改写成下面这样:

s := myStruct{"tony", 23}
a := [5]int{13, 14, 15, 16, 17}
sl := []int{23, 24, 25, 26, 27}
m := map[int]string {1:"hello", 2:"gopher", 3:"!"}

显然,最初的代码得到了大幅简化。

复合字面值由两部分组成:一部分是类型,比如上述示例代码中赋值操作符右侧的myStruct、[5]int、[]int和map[int]string;另一部分是由大括号{}包裹的字面值。这里的字面值形式仅仅是Go复合字面值作为值构造器的基本用法。下面来分别看看复合字面值对于不同复合类型的高级用法。