重点问题

  1. 输出的格式 (println!)

    定义并实例化结构体

    ```rust

struct User { username: String, email: String, sign_in_count: u64, active: bool, }

let user1 = User { email: String::from(“someone@example.com”), username: String::from(“someusername123”), active: true, sign_in_count: 1, };

let user2 = User { email: String::from(“another@example.com”), ..user1 }; //我们在创建 user2 后不能再使用 user1,因为 user1 的 username 字段中的 String 被移到 user2 中。 //如果我们给 user2 的 email 和 username 都赋予新的 String 值,从而只使用 user1 的 active 和 sign_in_count 值,那么 user1 在创建 user2 后仍然有效。

  1. 整个实例必须是可变的;Rust 并不允许只将某个字段标记为可变。可以在函数体的最后一个表达式中构造一个结构体的新实例,来隐式地返回这个实例。
  2. <a name="n4XRc"></a>
  3. ### 使用结构体更新语法从其它实例创建实例
  4. 类似于ES6的解构赋值。也遵守所有权的变量与数据交互的方式:移动和克隆。
  5. <a name="kPzbI"></a>
  6. ### 元祖结构体
  7. 没有具体的字段名,只有字段的类型。
  8. ```rust
  9. struct Color(i32, i32, i32);
  10. struct Point(i32, i32, i32);
  11. let black = Color(0, 0, 0);
  12. let origin = Point(0, 0, 0);

类单元结构体

没有任何字段的结构体。常常用在某个类型想要实现trait但不需要在类型中存储数据时发挥作用。

  1. struct AlwaysEqual;
  2. let subject = AlwaysEqual;

可以使结构体存储被其它对象拥有的数据的引用,不过需要和生命周期配合。

方法语法

结构体的方法第一个参数总是self,代表调用该方法的结构体实例。
&self 实际上是 self: &Self 的缩写。在一个 impl 块中,Self 类型是 impl 块的类型的别名。

  1. struct Rectangle {
  2. width: u32,
  3. height: u32,
  4. }
  5. impl Rectangle {
  6. fn area(&self) -> u32 {
  7. self.width * self.height
  8. }
  9. }

自动引用和解引用

方法调用是 Rust 中少数几个拥有这种行为的地方。

关联函数

所有在 impl 块中定义的函数被称为关联函数(associated functions),因为它们与 impl 后面命名的类型相关。我们可以定义不以 self 为第一参数的关联函数(因此不是方法),因为它们并不作用于一个结构体的实例。
不是方法的关联函数经常被用作返回一个结构体新实例的构造函数。
使用结构体名和 :: 语法来调用这个关联函数。