6.5. 匿名结构体
在本章前几节中,我们使用到的结构体都是按以下形式声明的:
type 类型名 struct {
成员列表
}
实际上该语法的内在含义是:
struct {...}
的部分定义了一个结构体;type 类型名
的部分为刚才定义的结构体赋予了一个名字。
那么在凹语言中,是否可以通过声明结构体字面量的方式直接创建一个结构体变量,而无需对该结构体命名?确实是可以的,这种用法被称为匿名结构体,例如:
// 版权 @2021 凹语言 作者。保留所有权利。
//全局匿名结构体变量:
global G: struct{
name: string
age: i32
}
func main {
G.name = "张三"
G.age = 88
println(G.name, " ", G.age) // 张三 88
//局部匿名结构体变量:
k := struct {name: string; age: i32}{name: "李四", age: 66}
println(k.name, " ", k.age) // 李四 66
G = k
println(G.name, " ", G.age) // 李四 66
}
由于匿名结构体没有类型名,因此声明匿名结构体变量时只能使用 变量名: struct{...}
或其快捷定义形式直接指定类型(结构体)。除此之外,匿名结构体以及其成员的使用,与普通的具名结构体基本一致。匿名结构体同样遵循0值初始化规则,其字面值中,未指定初始值的成员均为0值。
匿名结构体最常用的场景是全局配置变量。很多全局配置变量的类型,仅仅在声明该全局变量时会被使用一次,为仅存在一个实例的变量单独定义一个类型略显繁琐,此时即可使用匿名结构体替代(例如上例中的全局变量 G
)。
具名类型位于模块的名字空间下,但匿名结构体因为没有名字,其定义实际上位于全局空间,因此如果两个匿名结构体变量的内存布局完全一致(既成员个数、对应成员名、对应成员类型均一致),它们将被认为属于同一个类型,可以互相赋值(例如上例中的全局变量 G
和 局部变量 k
),哪怕这两个变量位于不同模块中,该特性依然成立;这引出了匿名结构体的另一个使用场景:跨模块传递参数。
由于匿名结构体没有类型名,因此按照语法规则,无法为其添加方法。