rusdlings move_semantics2 为什么传递引用不起作用?

问题描述 投票:0回答:3

我正在通过做restlings练习来尝试Rust,这是一个非常好的开始方法,但有一些我不明白的地方。

练习:move_semantics2

我知道,为了用 vec0 的内容初始化 vec1 而不剥夺所有权,我们必须克隆 vec0 或通过引用传递。问题是这段传递引用的代码似乎不起作用。

我想明白为什么,有什么想法吗?

// move_semantics2.rs
// Make me compile without changing line 13 or moving line 10!
// Execute `rustlings hint move_semantics2` 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);

    // Do not change the following line!
    println!("{} has length {} content `{:?}`", "vec0", vec0.len(), vec0);

    vec1.push(88);

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

fn fill_vec(vec: &Vec<i32>) -> &Vec<i32> {
    let mut vec = vec;

    vec.push(22);
    vec.push(44);
    vec.push(66);

    vec
}

这是我遇到的错误:

⚠️  Compiling of exercises/move_semantics/move_semantics2.rs failed! Please try again. Here's the output:
warning: variable does not need to be mutable
 --> exercises/move_semantics/move_semantics2.rs:8:9
  |
8 |     let mut vec1 = fill_vec(&vec0);
  |         ----^^^^
  |         |
  |         help: remove this `mut`
  |
  = note: `#[warn(unused_mut)]` on by default

error[E0596]: cannot borrow `*vec1` as mutable, as it is behind a `&` reference
  --> exercises/move_semantics/move_semantics2.rs:13:5
   |
8  |     let mut vec1 = fill_vec(&vec0);
   |         -------- consider changing this binding's type to be: `&mut Vec<i32>`
...
13 |     vec1.push(88);
   |     ^^^^^^^^^^^^^ `vec1` is a `&` reference, so the data it refers to cannot be borrowed as mutable

warning: variable does not need to be mutable
  --> exercises/move_semantics/move_semantics2.rs:19:9
   |
19 |     let mut vec = vec;
   |         ----^^^
   |         |
   |         help: remove this `mut`

error[E0596]: cannot borrow `*vec` as mutable, as it is behind a `&` reference
  --> exercises/move_semantics/move_semantics2.rs:21:5
   |
19 |     let mut vec = vec;
   |         ------- consider changing this binding's type to be: `&mut Vec<i32>`
20 |
21 |     vec.push(22);
   |     ^^^^^^^^^^^^ `vec` is a `&` reference, so the data it refers to cannot be borrowed as mutable

error[E0596]: cannot borrow `*vec` as mutable, as it is behind a `&` reference
  --> exercises/move_semantics/move_semantics2.rs:22:5
   |
19 |     let mut vec = vec;
   |         ------- consider changing this binding's type to be: `&mut Vec<i32>`
...
22 |     vec.push(44);
   |     ^^^^^^^^^^^^ `vec` is a `&` reference, so the data it refers to cannot be borrowed as mutable

error[E0596]: cannot borrow `*vec` as mutable, as it is behind a `&` reference
  --> exercises/move_semantics/move_semantics2.rs:23:5
   |
19 |     let mut vec = vec;
   |         ------- consider changing this binding's type to be: `&mut Vec<i32>`
...
23 |     vec.push(66);
   |     ^^^^^^^^^^^^ `vec` is a `&` reference, so the data it refers to cannot be borrowed as mutable

error: aborting due to 4 previous errors; 2 warnings emitted

For more information about this error, try `rustc --explain E0596`.
rust borrow-checker ownership
3个回答
1
投票

我认为你的误解源于

fill_vec()
中的这句话:

let mut vec = vec;

该行并没有复制原始向量,而是尝试使对传入向量的原始不可变引用可变,这自然是编译器不允许的。如果您的目的是复制传入向量,您会希望您的函数如下所示:

fn fill_vec(vec: &Vec<i32>) -> Vec<i32> {
    let mut new_vec = vec.clone();

    new_vec.push(22);
    new_vec.push(44);
    new_vec.push(66);

    new_vec
}

请注意,这个新版本使用

clone()
来复制原始向量,并且它返回一个新向量,而不是返回对向量的引用。


0
投票

因为这个问题的期望如下:

// Expected output:
// vec0 has length 3 content `[22, 44, 66]`
// vec1 has length 4 content `[22, 44, 66, 88]`

所以我认为下面是一个更好的解决方案。

let vec0 = Vec::new();

let vec0 = fill_vec(vec0);

// Do not move the following line!
let mut vec1 = vec0.clone();

0
投票
// Expected output:
// vec0 has length 3, with contents `[22, 44, 66]`
// vec1 has length 4, with contents `[22, 44, 66, 88]`

正确的应该是:

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

    let mut vec1 = fill_vec(&mut vec0);

    println!("{} has length {}, with contents: `{:?}`", "vec0", vec0.len(), vec0);

    vec1.push(88);

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

fn fill_vec(vec: &mut Vec<i32>) -> Vec<i32> {

    vec.push(22);
    vec.push(44);
    vec.push(66);

    vec.to_vec()
}

© www.soinside.com 2019 - 2024. All rights reserved.