• 二夕Thrower
    2023-10-23 来自浙江
    思考题 1: 无法通过编译,可以将第 5 行代码修改为:let tmp_s = s.clone(); 思考题 2: 由于 Point 没有实现 Copy trait,所以在赋值过程中会产生 Move。

    作者回复: 真棒!

    
    1
  • FRANK
    2023-10-24 来自安徽
    1. 编译器报错,提示s已经move。 error[E0382]: use of moved value: `s` 2. 编译器报错,提示如下: error[E0382]: borrow of moved value: `p1` --> src/main.rs:9:25 | 7 | let p1 = Point{x:1, y:1, z:1}; | -- move occurs because `p1` has type `Point`, which does not implement the `Copy` trait 8 | let p2 = p1; | -- value moved here 9 | println!("{:?}, {:?}", p1, p2); | ^^ value borrowed here after move

    作者回复: 对的

    
    
  • -Hedon🍭
    2023-10-23 来自湖北
    思考题1:编译报错。因为在第一次循环的时候,s 的所有权已经转移到 tmp_s 了,后面 s 已经是无效状态了,不能再转移所有权。 思考题2:移动。

    作者回复: 棒!

    
    
  • -Hedon🍭
    2023-10-23 来自湖北
    思考题1:编译报错。因为 s 的所有权在第一次循环的时候已经移动到 tmp_s 了,s 已经是处于无效状态了。

    作者回复: 厉害

    
    
  • julia
    2023-10-24 来自重庆
    1. String类型,实际数据在堆上存储。 let tmp_s = s 循环第一次的时候,会移动所有权,s在栈上的内存虽然还在,但是被编译器视为无效变量或无效状态,所以第二次及以后的循环就不能实验变量s了,编译器会报错。 2. 结构体类型默认没有实现Copy trait, 赋值过程也会移动所有权。 当然从底层看,这个Point结构体的成员都是基本类型(基本类型实现了Copy), 所以这个结构体的值是保存在栈上的,所以赋值操作,实际上底层是在栈上完整拷贝了一次Point结构体,但是编译器依然会把原来的Point结构体变量视为无效状态或无效变量。
    
    
  • 馍馍汉宝
    2023-10-24 来自广东
    2的解决方法: ```rs #[derive(Debug, Clone, Copy)] struct Point { x: i64, y: i64, z: i64} ```
    
    
  • 馍馍汉宝
    2023-10-24 来自广东
    2. Move
    
    
  • 刘永臣
    2023-10-24 来自北京
    问题1:本来以为坑在s 因为s在第一次遍历时已经转移了,所以第二次遍历肯定会出错,所以编译器会报错,没有问题;但是实际上循环条件中i 会被多次修改,所以声明i时也应该增加mut; 问题2:结构体数据复合结构,所以对其进行赋值是实际上进行了所有权的转移。
    
    
  • 馍馍汉宝
    2023-10-24 来自广东
    1. 会报错,甚至在编译之前,VSCode 就已经提前知道错误信息:use of moved value: `s` value moved here, in previous iteration of loop。并给出了对应的解决方案,加上 .clone(if the performance cost is acceptable)
    
    