2022-02-25 03:34:45 -06:00
|
|
|
|
# 所有权
|
|
|
|
|
|
2022-03-02 08:11:56 -06:00
|
|
|
|
1. 🌟🌟
|
2022-02-25 03:34:45 -06:00
|
|
|
|
```rust,editable
|
|
|
|
|
|
|
|
|
|
fn main() {
|
2022-03-02 03:32:22 -06:00
|
|
|
|
// 使用尽可能多的方法来通过编译
|
2022-02-25 03:34:45 -06:00
|
|
|
|
let x = String::from("hello, world");
|
|
|
|
|
let y = x;
|
|
|
|
|
println!("{},{}",x,y);
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
2022-03-02 08:11:56 -06:00
|
|
|
|
2. 🌟🌟
|
2022-02-25 03:34:45 -06:00
|
|
|
|
```rust,editable
|
|
|
|
|
// 不要修改 main 中的代码
|
|
|
|
|
fn main() {
|
|
|
|
|
let s1 = String::from("hello, world");
|
|
|
|
|
let s2 = take_ownership(s1);
|
|
|
|
|
|
|
|
|
|
println!("{}", s2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 只能修改下面的代码!
|
|
|
|
|
fn take_ownership(s: String) {
|
|
|
|
|
println!("{}", s);
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
2022-03-02 08:11:56 -06:00
|
|
|
|
3. 🌟🌟
|
2022-02-25 03:34:45 -06:00
|
|
|
|
```rust,editable
|
|
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
|
let s = give_ownership();
|
|
|
|
|
println!("{}", s);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 只能修改下面的代码!
|
|
|
|
|
fn give_ownership() -> String {
|
|
|
|
|
let s = String::from("hello, world");
|
|
|
|
|
// convert String to Vec
|
|
|
|
|
// 将 String 转换成 Vec 类型
|
|
|
|
|
let _s = s.into_bytes();
|
|
|
|
|
s
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
2022-03-02 08:11:56 -06:00
|
|
|
|
4. 🌟🌟
|
2022-02-25 03:34:45 -06:00
|
|
|
|
```rust,editable
|
2022-03-02 03:32:22 -06:00
|
|
|
|
// 修复错误,不要删除任何代码行
|
2022-02-25 03:34:45 -06:00
|
|
|
|
fn main() {
|
|
|
|
|
let s = String::from("hello, world");
|
|
|
|
|
|
|
|
|
|
print_str(s);
|
|
|
|
|
|
|
|
|
|
println!("{}", s);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn print_str(s: String) {
|
|
|
|
|
println!("{}",s)
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
2022-03-02 08:11:56 -06:00
|
|
|
|
5. 🌟🌟
|
2022-10-10 21:43:03 -05:00
|
|
|
|
```rust,editable
|
2022-02-25 03:34:45 -06:00
|
|
|
|
// 不要使用 clone,使用 copy 的方式替代
|
|
|
|
|
fn main() {
|
2022-03-02 03:32:22 -06:00
|
|
|
|
let x = (1, 2, (), "hello".to_string());
|
2022-02-25 03:34:45 -06:00
|
|
|
|
let y = x.clone();
|
|
|
|
|
println!("{:?}, {:?}", x, y);
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
2022-02-25 07:50:28 -06:00
|
|
|
|
#### 可变性
|
|
|
|
|
当所有权转移时,可变性也可以随之改变。
|
|
|
|
|
|
2022-03-02 08:11:56 -06:00
|
|
|
|
6. 🌟
|
2022-02-25 07:50:28 -06:00
|
|
|
|
```rust,editable
|
|
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
|
let s = String::from("hello, ");
|
|
|
|
|
|
|
|
|
|
// 只修改下面这行代码 !
|
|
|
|
|
let s1 = s;
|
|
|
|
|
|
|
|
|
|
s1.push_str("world")
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
2022-03-02 08:11:56 -06:00
|
|
|
|
7. 🌟🌟🌟
|
2022-02-25 07:50:28 -06:00
|
|
|
|
```rust,editable
|
|
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
|
let x = Box::new(5);
|
|
|
|
|
|
|
|
|
|
let ... // 完成该行代码,不要修改其它行!
|
|
|
|
|
|
|
|
|
|
*y = 4;
|
|
|
|
|
|
|
|
|
|
assert_eq!(*x, 5);
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 部分 move
|
|
|
|
|
当解构一个变量时,可以同时使用 `move` 和引用模式绑定的方式。当这么做时,部分 `move` 就会发生:变量中一部分的所有权被转移给其它变量,而另一部分我们获取了它的引用。
|
|
|
|
|
|
|
|
|
|
在这种情况下,原变量将无法再被使用,但是它没有转移所有权的那一部分依然可以使用,也就是之前被引用的那部分。
|
|
|
|
|
|
|
|
|
|
#### 示例
|
|
|
|
|
```rust,editable
|
|
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
|
struct Person {
|
|
|
|
|
name: String,
|
|
|
|
|
age: Box<u8>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let person = Person {
|
|
|
|
|
name: String::from("Alice"),
|
|
|
|
|
age: Box::new(20),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 通过这种解构式模式匹配,person.name 的所有权被转移给新的变量 `name`
|
2022-08-21 04:23:42 -05:00
|
|
|
|
// 但是,这里 `age` 变量却是对 person.age 的引用, 这里 ref 的使用相当于: let age = &person.age
|
2022-02-25 07:50:28 -06:00
|
|
|
|
let Person { name, ref age } = person;
|
|
|
|
|
|
|
|
|
|
println!("The person's age is {}", age);
|
|
|
|
|
|
|
|
|
|
println!("The person's name is {}", name);
|
|
|
|
|
|
|
|
|
|
// Error! 原因是 person 的一部分已经被转移了所有权,因此我们无法再使用它
|
|
|
|
|
//println!("The person struct is {:?}", person);
|
|
|
|
|
|
|
|
|
|
// 虽然 `person` 作为一个整体无法再被使用,但是 `person.age` 依然可以使用
|
|
|
|
|
println!("The person's age from person struct is {}", person.age);
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### 练习
|
|
|
|
|
|
2022-03-02 08:11:56 -06:00
|
|
|
|
8. 🌟
|
2022-02-25 07:50:28 -06:00
|
|
|
|
```rust,editable
|
|
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
|
let t = (String::from("hello"), String::from("world"));
|
|
|
|
|
|
|
|
|
|
let _s = t.0;
|
|
|
|
|
|
|
|
|
|
// 仅修改下面这行代码,且不要使用 `_s`
|
|
|
|
|
println!("{:?}", t);
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
2022-03-02 08:11:56 -06:00
|
|
|
|
9. 🌟🌟
|
2022-02-25 07:50:28 -06:00
|
|
|
|
```rust,editable
|
|
|
|
|
|
|
|
|
|
fn main() {
|
|
|
|
|
let t = (String::from("hello"), String::from("world"));
|
|
|
|
|
|
|
|
|
|
// 填空,不要修改其它代码
|
2022-03-02 03:32:22 -06:00
|
|
|
|
let (__, __) = __;
|
2022-02-25 07:50:28 -06:00
|
|
|
|
|
2022-03-02 03:32:22 -06:00
|
|
|
|
println!("{:?}, {:?}, {:?}", s1, s2, t); // -> "hello", "world", ("hello", "world")
|
2022-02-25 07:50:28 -06:00
|
|
|
|
}
|
2022-03-01 08:06:38 -06:00
|
|
|
|
```
|
|
|
|
|
|
2022-05-13 12:21:34 -05:00
|
|
|
|
> 你可以在[这里](https://github.com/sunface/rust-by-practice/blob/master/solutions/ownership/ownership.md)找到答案(在 solutions 路径下)
|