update ownership.md;

This commit is contained in:
sunface 2022-02-25 21:50:28 +08:00
parent 3322f7908f
commit c880d4d6a4
3 changed files with 185 additions and 2 deletions

View File

@ -1,6 +1,6 @@
# Ownership
🌟🌟
🌟🌟
```rust,editable
fn main() {
@ -71,3 +71,93 @@ fn main() {
}
```
#### Mutability
Mutability can be changed when ownership is transferred.
🌟
```rust,editable
fn main() {
let s = String::from("hello, ");
// modify this line only !
let s1 = s;
s1.push_str("world")
}
```
🌟🌟🌟
```rust,editable
fn main() {
let x = Box::new(5);
let ... // implement this line, dont change other lines!
*y = 4;
assert_eq!(*x, 5);
}
```
### Partial move
Within the destructuring of a single variable, both by-move and by-reference pattern bindings can be used at the same time. Doing this will result in a partial move of the variable, which means that parts of the variable will be moved while other parts stay. In such a case, the parent variable cannot be used afterwards as a whole, however the parts that are only referenced (and not moved) can still be used.
#### Example
```rust,editable
fn main() {
#[derive(Debug)]
struct Person {
name: String,
age: Box<u8>,
}
let person = Person {
name: String::from("Alice"),
age: Box::new(20),
};
// `name` is moved out of person, but `age` is referenced
let Person { name, ref age } = person;
println!("The person's age is {}", age);
println!("The person's name is {}", name);
// Error! borrow of partially moved value: `person` partial move occurs
//println!("The person struct is {:?}", person);
// `person` cannot be used but `person.age` can be used as it is not moved
println!("The person's age from person struct is {}", person.age);
}
```
#### Exercises
🌟
```rust,editable
fn main() {
let t = (String::from("hello"), String::from("world"));
let _s = t.0;
// modify this line only, don't use `_s`
println!("{:?}", t);
}
```
🌟🌟
```rust,editable
fn main() {
let t = (String::from("hello"), String::from("world"));
// fill the blanks
let (__, __) = t;
println!("{:?}, {:?}, {:?}", s1, s2, t);
}
```

View File

@ -7,7 +7,7 @@
- [字符、布尔、单元类型](basic-types/char-bool-unit.md)
- [语句与表达式](basic-types/statements-expressions.md)
- [函数](basic-types/functions.md)
- [所有权和借用 todo](ownership/intro.md)
- [所有权和借用](ownership/intro.md)
- [所有权](ownership/ownership.md)
- [引用和借用](ownership/borrowing.md)
- [复合类型 todo](compound-types/intro.md)

View File

@ -72,3 +72,96 @@ fn main() {
}
```
#### 可变性
当所有权转移时,可变性也可以随之改变。
🌟
```rust,editable
fn main() {
let s = String::from("hello, ");
// 只修改下面这行代码 !
let s1 = s;
s1.push_str("world")
}
```
🌟🌟🌟
```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`
// 但是,这里 `age` 变量确是对 person.age 的引用, 这里 ref 的使用相当于: let age = &person.age
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);
}
```
#### 练习
🌟
```rust,editable
fn main() {
let t = (String::from("hello"), String::from("world"));
let _s = t.0;
// 仅修改下面这行代码,且不要使用 `_s`
println!("{:?}", t);
}
```
🌟🌟
```rust,editable
fn main() {
let t = (String::from("hello"), String::from("world"));
// 填空,不要修改其它代码
let (__, __) = t;
println!("{:?}, {:?}, {:?}", s1, s2, t);
}
```