移动并返回一个可变指针

Nat*_*ara 1 memory ownership rust

我正在通过这个 Rust教程,我正在尝试解决这个问题:

实现一个函数,incrementMut它将整数向量作为输入,并通过将每个值递增1来修改原始列表的值.

这似乎是一个相当简单的问题,是吗?

我一直试图找到一段时间的编译解决方案,但我开始失去希望.这是我到目前为止:

fn main() {
    let mut p = vec![1i, 2i, 3i];
    increment_mut(p);

    for &x in p.iter() {
        print!("{} ", x);
    }
    println!("");
}

fn increment_mut(mut x: Vec<int>) {
    for &mut i in x.iter() {
        i += 1;
    }
}
Run Code Online (Sandbox Code Playgroud)

这是编译器在我尝试编译时所说的内容:

Compiling tut2 v0.0.1 (file:///home/nate/git/rust/tut2)
/home/nate/git/rust/tut2/src/main.rs:5:12: 5:13 error: use of moved value: `p`
/home/nate/git/rust/tut2/src/main.rs:5  for &x in p.iter() {
                                                  ^
/home/nate/git/rust/tut2/src/main.rs:3:16: 3:17 note: `p` moved here because it has type `collections::vec::Vec<int>`, which is non-copyable
/home/nate/git/rust/tut2/src/main.rs:3  increment_mut(p);
                                                      ^
error: aborting due to previous error
Could not compile `tut2`.

To learn more, run the command again with --verbose.
Run Code Online (Sandbox Code Playgroud)

我也试过一个带引用的版本:

fn main() {
    let mut p = vec![1i, 2i, 3i];
    increment_mut(&p);

    for &x in p.iter() {
        print!("{} ", x);
    }
    println!("");
}

fn increment_mut(x: &mut Vec<int>) {
    for &mut i in x.iter() {
        i += 1i;
    }
}
Run Code Online (Sandbox Code Playgroud)

而错误:

Compiling tut2 v0.0.1 (file:///home/nate/git/rust/tut2)
/home/nate/git/rust/tut2/src/main.rs:3:16: 3:18 error: cannot borrow immutable dereference of `&`-pointer as mutable
/home/nate/git/rust/tut2/src/main.rs:3  increment_mut(&p);
                                                      ^~
error: aborting due to previous error
Could not compile `tut2`.

To learn more, run the command again with --verbose.
Run Code Online (Sandbox Code Playgroud)

我觉得我在Rust中缺少一些关于内存所有权的核心想法,并且它正在解决像这样的琐碎问题非常困难,有人可以对此有所了解吗?

Chr*_*gan 6

您的代码中存在一些错误.

  1. increment_mut(&p)如果是p这样Vec<int>,就需要这个功能increment_mut(&Vec<int>); &-references和&mut-references在语法上是完全不同的东西,如果你想要一个&mut参考,你必须写&mut p,而不是&p.

  2. 您需要了解模式及其运作方式; for &mut i in x.iter()不会做你它打算:它会做的是采取&int的是每次迭代x.iter()产生,取消对它的引用(的&),复制值(因为int满足Copy,如果你用非试过Copy型像String它不会编译) ,并将其放在mutable变量i(mut i)中.也就是说,它相当于for i in x.iter() { let mut i = *i; … }.这样做的效果i += 1实际上只是递增局部变量而对矢量没有影响.您可以通过使用iter_mut生成&mut int而不是&int,并将&mut i模式更改为just ii += 1to来解决此问题*i += 1,意思是"改变int内心&mut int.

您也可以通过调用矢量从使用切换&mut Vec<int>到使用.这是一种更好的做法; 实际上你应该永远不需要对向量的引用,因为它需要两个级别的间接,只需要一个.同上- 非常罕见,你应该在这种情况下使用.&mut [int].as_mut_slice()&String&str

那么:

fn main() {
    let mut p = vec![1i, 2i, 3i];
    increment_mut(p.as_mut_slice());

    for &x in p.iter() {
        print!("{} ", x);
    }
    println!("");
}

fn increment_mut(x: &mut [int]) {
    for i in x.iter_mut() {
        *i += 1;
    }
}
Run Code Online (Sandbox Code Playgroud)