Rust学习——TRPL-Part6

Using Structs to Structure Related Data

Structs and enums are the building blocks for ccrating new types in your program's domain to take full advantage of Rust's compile time type checking.

Defining and Instantiating Structs

1
2
3
4
5
6
struct User {
username: String,
email: String,
sign_in_count: u64,
active: bool,
}

Creating Instances From Other Instances With Struct Update Syntax

使用旧实例的大部分值但改变其部分值来创建一个新的结构体实例通常是很有用的。这可以通过结构体更新语法(struct update syntax)实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#![allow(unused)]
fn main() {
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
};
}

请注意,结构更新语法就像带有 = 的赋值,因为它移动了数据,就像我们在所有权中Move情况讲到的一样。在这个例子中 我们在创建user2后不能再使用user1,因为user1username字段中的String 被移到user2中。如果我们给user2emailusername都赋予新的String值,从而只使用user1activesign_in_countactivesign_in_count的类型是实现Copy trait的类型,分配在栈上?),那么user1在创建user2后仍然有效,所以我们在所有权中Clone部分讨论同样适用。

Note that the entire instance must be mutable.

Using the Field Init Shorthand

1
2
3
4
5
6
7
8
fn build_user(email: String, username: String) -> User {
User {
email,
username,
active: true,
sign_in_count: 1,
}
}

Using Tuple Structs without Named Fields to Create Different Types

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

let black = Color(0, 0, 0);
let origin = Point(0, 0, 0);

Unit-Like Structs Without Any Fields

unit-like structs -- similar to ().

Unit-like structs can be useful in situations in which you need to implement a trait on some type but don’t have any data that you want to store in the type itself.

Ownership of Struct Data

Lifetime, can't store &str(slice), only String.

In Chapter 10, we’ll discuss how to fix these errors so you can store references in structs, but for now, we’ll fix errors like these using owned types like String instead of references like &str.

Method Syntax

Methods与functions异同:

相同点:都有fn关键字声明以及他们的名字,他们拥有参数和一个返回值,并包含在其他地方被调用时运行的代码。

不同点:methods被定义在struct(或者 enum 或者 trait object)的上下文中。

To define the function within the context of Rectangle, we start an impl (implementation) block.

Where's the -> Operator?

Rust doesn’t have an equivalent to the -> operator; instead, Rust has a feature called automatic referencing and dereferencing. Calling methods is one of the few places in Rust that has this behavior.

Here’s how it works: when you call a method with object.something(), Rust automatically adds in &, &mut, or * so object matches the signature of the method. In other words, the following are the same:

1
2
p1.distance(&p2);
(&p1).distance(&p2);

Associated Functions

Another useful feature of impl blocks is that we’re allowed to define functions within impl blocks that don’t take self as a parameter. These are called associated functions because they’re associated with the struct. They’re still functions, not methods, because they don’t have an instance of the struct to work with. You’ve already used the String::from associated function.

不是methods,因为没有关联的实例。

Associated functions are often used for constructors.

1
2
3
4
5
6
7
8
impl Rectangle {
fn square(size: u32) -> Rectangle {
Rectangle {
width: size,
height: size,
}
}
}