6.1. 结构体

凹语言中结构体声明的一般形式为:

type 类型名 struct {
    成员列表
}

其中成员列表的部分与变量声明格式一致,比如下例:

// 版权 @2023 凹语言 作者。保留所有权利。

type Info struct {
    name: string
    age:  i32
}

func PrintInfo(i: Info) {
    println("名字:", i.name, ",年龄:", i.age)
}

func main {
    i: Info
    i.name = "张三"
    i.age = 35
    PrintInfo(i) // 名字: 张三 ,年龄: 35
}

与很多语言类似,凹语言 使用选择操作符 . 访问结构体值的成员。另外需要特别注意的是,选择操作符 . 也可以用于访问结构体引用的成员,例如:

// 版权 @2023 凹语言 作者。保留所有权利。

type Info struct {
    name: string
    age:  i32
}

func GetInfo() => *Info {
    i: Info
    i.name = "李四"
    i.age = 42
    return &i
}

func main {
    j := GetInfo() // j 的类型是引用, *Info
    println(j.name, j.age) // 李四 42
}

由此可见,无论是值还是引用,访问其成员的方式是一致的,这与 C 语言不同(C 语言使用 -> 访问结构体指针的成员)。

结构体的成员类型,不能包含结构体本身,因为这会引起无限嵌套;事实上任何会引起无限嵌套的结构体都是非法的,比如两个结构体互相包含对方。但是结构体中包含本类型的引用是合法的(因为引用的实质是指针),这种用法常用于创建链表结构,比如:

type Node struct {
    data: i32
    next: *Node
}

结构体字面值的例子如下:

// 版权 @2023 凹语言 作者。保留所有权利。

type Info struct {
    name: string
    age:  i32
}

func main {
    i := Info{name: "王五"}
    println(j.name, j.age) // 王五 0
}

在声明结构体字面值时 {} 内为成员字面值列表,未列出的成员为 0 值。

如果结构体内的所有成员变量都可比(既该成员类型的变量间可执行 == 操作),则该结构体的变量间也可比。在目前已介绍的数据类型中,切片是不可比类型,因此直接或间接包含切片的结构体均不可比。与其他类型的声明类似,结构体可在模块内的任意文件中声明,且无需“先声明再使用”。