Ray 的记录站

日常开发实践记录

0%

Rust struct 基础

Struct 作为 Rust 语言的基础组成, 需要熟悉其用法.

Rust 中的 Struct

Struct 主要就是语法上的内容, 列于如下:

  1. 定义 struct 的示例:

    1
    2
    3
    4
    5
    6
    struct User {
    active: bool,
    username: String,
    email: String,
    sign_in_count: u64,
    }
  2. 创建 struct 对象:

    1
    2
    3
    4
    5
    6
    let user1 = User {
    email: String::from("[email protected]"),
    username: String::from("someusername123"),
    active: true,
    sign_in_count: 1,
    };
  3. 创建可变对象(Rust 没有单个属性可变的语法):

    1
    2
    3
    4
    5
    6
    7
    8
    let mut user1 = User {
    email: String::from("[email protected]"),
    username: String::from("someusername123"),
    active: true,
    sign_in_count: 1,
    };

    user1.email = String::from("[email protected]");
  4. struct 的”构造函数”定义:

    1
    2
    3
    4
    5
    6
    7
    8
    fn new(email: String, username: String) -> User {
    User {
    email: email,
    username: username,
    active: true,
    sign_in_count: 1,
    }
    }
  5. 属性赋值的简单语法:

    1
    2
    3
    4
    5
    6
    7
    8
    fn new(email: String, username: String) -> User {
    User {
    email,
    username,
    active: true,
    sign_in_count: 1,
    }
    }
  6. 根据一个 struct 创建新 struct 语法:

    1
    2
    3
    4
    5
    // 即只修改想要的, 其余部分展开到新 struct 中, 展开需要放到末尾写
    let user2 = User {
    email: String::from("[email protected]"),
    ..user1
    };

    注意上面的 user1 被 move 了, 因为剩余被展开的成员中包含 String(堆内存分配的), 如果上述 username 也是自己创建的新值, 则不会对 user1 move, 因为剩余的成员都是栈内存拷贝的.

  7. Tuple struct 的语法:

    1
    2
    3
    4
    5
    6
    7
    struct Color(i32, i32, i32);
    struct Point(i32, i32, i32);

    fn main() {
    let black = Color(0, 0, 0);
    let origin = Point(0, 0, 0);
    }

    使用 Tuple struct 的目的是区分不同类型的 Tuple(即便 Tuple 中的成员都相同), 且同样可以使用.语法来访问成员.

  8. Unit Like struct 的语法:

    1
    2
    3
    4
    5
    struct AlwaysEqual;

    fn main() {
    let subject = AlwaysEqual;
    }

    后续可以看到它的使用, 比如可以通过这种零数据的 struct 实现任意 trait.

Struct 的成员 Ownership 概述

struct 内部成员的 owner 就是该 struct.

比如上面定义过的 User struct, 在它里面选择的是 String 成员而非 &str 引用成员. 原因是想让 struct 对该成员持有, 且成员生命期就和 struct 的生命期一致了.

当然 struct 也可以有引用成员, 这就需要牵扯到生命期标记, 之后再讲.

struct 方法实现

主要还是语法:

  1. 方法定义和使用:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    #[derive(Debug)]
    struct Rectangle {
    width: u32,
    height: u32,
    }

    impl Rectangle {
    fn area(&self) -> u32 {
    self.width * self.height
    }
    }

    fn main() {
    let rect1 = Rectangle {
    width: 30,
    height: 50,
    };

    println!(
    "The area of the rectangle is {} square pixels.",
    rect1.area()
    );
    }

    方法参数第一个总是如下的其中一个:

    • self: 若 struct 不是 Copy 实现, 会将 struct 对象 move 到方法中(获取 ownership)
    • &self: 仅不可变引用该 struct 对象
    • &mut self: 该 struct 对象的可变引用
  2. 在方法调用时, 由于 Rust 有自动的引用和解引用(自动添加 &, &mut, *), 因此如果是 &self 的方法, 也无需手动写类似 (&user).some_method(), 而是直接 user.some_method() 即可.

  3. 关联函数: 即其他语言中类方法.

1
2
3
4
5
6
7
8
impl Rectangle {
fn square(size: u32) -> Self {
Self {
width: size,
height: size,
}
}
}
  1. 一个 struct 可以有多个 impl 块, 这样可以非常方便地分离多组方法实现.