Skip to content

结构体

命名结构体 named struct

named struct 和 Goland 的 struct 类似。

定义结构体:

struct 结构体名 {
    字段名: 类型,
    字段名: 类型,
    ......
}

构造结构体实例:

let 实例名 = 结构体名{
    字段名: ,
    字段名: ,
    ......
}

let 实例名 = 结构体名{
    ,
    ,
    ......
}

let 实例名2 = 结构体名{
    字段名: ,
    字段名: ,
    ..实例名1
}

实例化结构体时,可以写出字段,这样赋值可以不按照定义时的字段的顺序,也可以不写出字段,但这样必须按照定义时的字段顺序。

除此之外还可以使用 ..其他实例名 的方式借用或拷贝其他实例剩余字段的值。

Warning

注意 Rust 的结构体在构造时需给所有字段赋值。

使用这种第三种方式的时候,如果被拷贝的实例的字段不是可拷贝的,那么它的所有权会被移到新的结构体上。

struct Person{
    name: String,
    age u32,
}

fn main() {
    let s1 = Person{
        name: String::from("Boii");
        age: 18,
    };

    let s2 = Person{
        ..s1
    }
    println!("{}", s2.age);     // 18
    println!("{}", s2.name);    // Boii

    println!("{}", s1.age);     // age 是可拷贝的,所以 s1.age 不会失去所有权
    println!("{}", s1.name);    // s1 的 name 字段已经被移到 s2.name 上了,所以这里 s1.name 已经变成为初始化的状态,打印她会报错
}

如果不希望 s1 失去所有权,可以使用 .clone()。

fn main() {
    let s1 = Person{
        name: String::from("Boii");
        age: 18,
    };

    let s2 = Person{
        ..s1.clone()    // 使用克隆
    }
    println!("{}", s2.age);     // 18
    println!("{}", s2.name);    // Boii

    println!("{}", s1.age);     // age 是可拷贝的,所以 s1.age 不会失去所有权
    println!("{}", s1.name);    // s1 的 name 字段只是被克隆,所以这里 s1.name 依然不变,可以正常使用
}

元组结构体 tuple struct

除了 named struct 之外, Rust 提供了一种 tuple struct (元组结构体),非常适合一些少量字段的结构。

例如颜色、坐标:

struct Color(u8, u8, u8);
struct Point2d(f64, f64);

let red = Color(0xFF, 0, 0);// 赋值
let Color(r, g, b) = red;   // 解构

空结构体 unit-like struct

结构体内部可以没有任何字段,这样的结构体实例内存占用为 0,但定义后面不可以加大括号(除了1.9 nightly)。

但我们可以对空结构体实现她的成员函数。

struct emptySt;

let empty = emptySt;

impl someTrait for emptySt {
    ...
}

当我们只想关心该类型的行为,不想关心该类型的内容时,就非常使用和空结构体。