重点问题
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 后仍然有效。
整个实例必须是可变的;Rust 并不允许只将某个字段标记为可变。可以在函数体的最后一个表达式中构造一个结构体的新实例,来隐式地返回这个实例。
<a name="n4XRc"></a>
### 使用结构体更新语法从其它实例创建实例
类似于ES6的解构赋值。也遵守所有权的变量与数据交互的方式:移动和克隆。
<a name="kPzbI"></a>
### 元祖结构体
没有具体的字段名,只有字段的类型。
```rust
struct Color(i32, i32, i32);
struct Point(i32, i32, i32);
let black = Color(0, 0, 0);
let origin = Point(0, 0, 0);
类单元结构体
没有任何字段的结构体。常常用在某个类型想要实现trait但不需要在类型中存储数据时发挥作用。
struct AlwaysEqual;
let subject = AlwaysEqual;
可以使结构体存储被其它对象拥有的数据的引用,不过需要和生命周期配合。
方法语法
结构体的方法第一个参数总是self,代表调用该方法的结构体实例。
&self 实际上是 self: &Self 的缩写。在一个 impl 块中,Self 类型是 impl 块的类型的别名。
struct Rectangle {
width: u32,
height: u32,
}
impl Rectangle {
fn area(&self) -> u32 {
self.width * self.height
}
}
自动引用和解引用
关联函数
所有在 impl 块中定义的函数被称为关联函数(associated functions),因为它们与 impl 后面命名的类型相关。我们可以定义不以 self 为第一参数的关联函数(因此不是方法),因为它们并不作用于一个结构体的实例。
不是方法的关联函数经常被用作返回一个结构体新实例的构造函数。
使用结构体名和 :: 语法来调用这个关联函数。