所有权

  1. 🌟🌟
2. fn main() {
3. // 使用尽可能多的方法来通过编译
4. let x = String::from("hello, world");
5. let y = x;
6. println!("{},{}",x,y);
7. }
  1. 🌟🌟
1. // 不要修改 main 中的代码
2. fn main() {
3. let s1 = String::from("hello, world");
4. let s2 = take_ownership(s1);

6. println!("{}", s2);
7. }

9. // 只能修改下面的代码!
10. fn take_ownership(s: String) {
11. println!("{}", s);
12. }
  1. 🌟🌟
2. fn main() {
3. let s = give_ownership();
4. println!("{}", s);
5. }

7. // 只能修改下面的代码!
8. fn give_ownership() -> String {
9. let s = String::from("hello, world");
10. // convert String to Vec
11. // 将 String 转换成 Vec 类型
12. let _s = s.into_bytes();
13. s
14. }
  1. 🌟🌟
1. // 修复错误,不要删除任何代码行
2. fn main() {
3. let s = String::from("hello, world");

5. print_str(s);

7. println!("{}", s);
8. }

10. fn print_str(s: String)  {
11. println!("{}",s)
12. }
  1. 🌟🌟
1. // 不要使用 clone,使用 copy 的方式替代
2. fn main() {
3. let x = (1, 2, (), "hello".to_string());
4. let y = x.clone();
5. println!("{:?}, {:?}", x, y);
6. }

可变性

当所有权转移时,可变性也可以随之改变。

  1. 🌟
2. fn main() {
3. let s = String::from("hello, ");

5. // 只修改下面这行代码 !
6. let s1 = s;

8. s1.push_str("world")
9. }
  1. 🌟🌟🌟
2. fn main() {
3. let x = Box::new(5);

5. let ...      // 完成该行代码,不要修改其它行!

7. *y = 4;

9. assert_eq!(*x, 5);
10. }

部分 move

当解构一个变量时,可以同时使用 move 和引用模式绑定的方式。当这么做时,部分 move 就会发生:变量中一部分的所有权被转移给其它变量,而另一部分我们获取了它的引用。

在这种情况下,原变量将无法再被使用,但是它没有转移所有权的那一部分依然可以使用,也就是之前被引用的那部分。

示例

2. fn main() {
3. #[derive(Debug)]
4. struct Person {
5. name: String,
6. age: Box<u8>,
7. }

9. let person = Person {
10. name: String::from("Alice"),
11. age: Box::new(20),
12. };

14. // 通过这种解构式模式匹配,person.name 的所有权被转移给新的变量 `name`
15. // 但是,这里 `age` 变量却是对 person.age 的引用, 这里 ref 的使用相当于: let age = &person.age
16. let Person { name, ref age } = person;

18. println!("The person's age is {}", age);

20. println!("The person's name is {}", name);

22. // Error! 原因是 person 的一部分已经被转移了所有权,因此我们无法再使用它
23. //println!("The person struct is {:?}", person);

25. // 虽然 `person` 作为一个整体无法再被使用,但是 `person.age` 依然可以使用
26. println!("The person's age from person struct is {}", person.age);
27. }

练习

  1. 🌟
2. fn main() {
3. let t = (String::from("hello"), String::from("world"));

5. let _s = t.0;

7. // 仅修改下面这行代码,且不要使用 `_s`
8. println!("{:?}", t);
9. }
  1. 🌟🌟
2. fn main() {
3. let t = (String::from("hello"), String::from("world"));

5. // 填空,不要修改其它代码
6. let (__, __) = __;

8. println!("{:?}, {:?}, {:?}", s1, s2, t); // -> "hello", "world", ("hello", "world")
9. }

你可以在这里找到答案(在 solutions 路径下)