Skip to content
On this page

Move语义3: exercises/move_semantics/move_semantics3.rs

题目

rust
// move_semantics3.rs
//
// Make me compile without adding new lines-- just changing existing lines! (no
// lines with multiple semicolons necessary!)
//
// Execute `rustlings hint move_semantics3` or use the `hint` watch subcommand
// for a hint.

// I AM NOT DONE

fn main() {
    let vec0 = Vec::new();

    let mut vec1 = fill_vec(vec0);

    println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);

    vec1.push(88);

    println!("{} has length {} content `{:?}`", "vec1", vec1.len(), vec1);
}

fn fill_vec(vec: Vec<i32>) -> Vec<i32> {
    vec.push(22);
    vec.push(44);
    vec.push(66);

    vec
}

题目要求我们在只修改现有行,不添加新行的情况下,实现编译通过。

题目解析

这个和上一个题目相比,不同之处在于fn fill_vec的第一行let mut vec = vec;没有了。

我们来看编译器给出的信息:

txt
⚠️  Compiling of exercises/move_semantics/move_semantics3.rs failed! Please try again. Here's the output:
error[E0596]: cannot borrow `vec` as mutable, as it is not declared as mutable
  --> exercises/move_semantics/move_semantics3.rs:23:13
   |
23 | fn fill_vec(vec: Vec<i32>) -> Vec<i32> {
   |             ^^^ not mutable
24 |     vec.push(22);
   |     ------------ cannot borrow as mutable
25 |     vec.push(44);
   |     ------------ cannot borrow as mutable
26 |     vec.push(66);
   |     ------------ cannot borrow as mutable
   |
help: consider changing this to be mutable
   |
23 | fn fill_vec(mut vec: Vec<i32>) -> Vec<i32> {
   |             +++

error: aborting due to previous error

For more information about this error, try `rustc --explain E0596`.

我们可以读出如下信息:

  • vec定义的是不可变的,而函数内使用push方法对vec进行了修改
  • 编译器提示我们需要将参数定义为可变的fn fill_vec(mut vec: Vec<i32>) -> Vec<i32>
rust
fn fill_vec(vec: Vec<i32>) -> Vec<i32> { 
fn fill_vec(mut vec: Vec<i32>) -> Vec<i32> { 
    vec.push(22);
    vec.push(44);
    vec.push(66);

    vec
}

我们来分析以下,在main函数中,调用函数fill_vec来生成vec1,后续没有针对vec0的读取,所以这里转移所有权也无所谓。

fill_vec函数中,因为vec0的所有权转移给了vec,而函数内对vec进行了修改,但是函数声明里的参数是不可变的,所以我们要将其修改为可变的。

参考资料

Powered by VitePress