Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

结构体

结构体用于把相关数据组合成一个命名类型。 当多个值总是一起出现时,把它们放进结构体通常会让代码更清晰。

定义结构体

使用 struct 定义结构体:

struct Foo {
    x: i32,
    y: i32,
}

Foo 有两个字段:xy。字段名后面写类型。

字段默认私有。需要让声明模块之外的代码构造、读取或解构字段时,在字段前添加 pub

pub struct Point {
    pub x: i32,
    pub y: i32,
}

私有字段仍可在声明模块及其子模块中使用,通常通过公开的构造函数和方法对外提供受控访问。

创建结构体值

可以使用结构体字面量创建值:

fun main() {
    let foo = Foo { x: 1, y: 1 };
    print!("{}", foo.x)
}

字段访问使用点号:

foo.x
foo.y

当局部变量名和字段名相同时,可以使用字段简写:

fun make_foo(x: i32, y: i32) -> Foo {
    Foo { x, y }
}

结构体字面量会检查字段是否可见、是否存在、是否缺失以及字段类型是否匹配。

泛型结构体

结构体可以带类型参数和 const 参数,规则见泛型一章。

关联函数

可以在 impl 块中给结构体定义关联函数,并通过 Type::function(...) 调用:

impl Foo {
    fun new(x: i32, y: i32) -> Foo {
        Foo { x, y }
    }
}

fun main() {
    let foo = Foo::new(1, 2);
}

结构体值会被移动

结构体也是普通值,因此遵循移动语义:

fun take(foo: Foo) {
    print!("{}", foo.x)
}

fun main() {
    let foo = Foo { x: 1, y: 1 };
    take(foo);
    print!("{}", foo); // error: foo 已经被移动
}

如果你只是想临时使用它,可以传引用:

fun inspect(foo: &Foo) {
    print!("{}", foo.x)
}

fun main() {
    let foo = Foo { x: 1, y: 1 };
    inspect(&foo);
    print!("{}", foo)
}

只要引用没有逃逸当前作用域,foo 仍然可以保持栈分配。