移动并返回一个可变指针

时间:2014-12-31 02:54:40

标签: memory rust ownership

我正在通过this 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;
    }
}

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

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.

我还尝试了一个带引用的版本:

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;
    }
}

错误:

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.

我觉得我在Rust中错过了关于内存所有权的一些核心理念,并且它正在解决这样的琐碎问题非常困难,有人会对此有所了解吗?

1 个答案:

答案 0 :(得分:6)

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

  1. increment_mut(&p),如果pVec<int>,则需要increment_mut(&Vec<int>)函数; & - 引用和&mut - 引用在语法上完全不同,如果您想要&mut - 引用,则必须编写&mut p,而不是&p。< / p>

  2. 您需要了解模式及其运作方式; for &mut i in x.iter()按照您的意图执行操作:它将执行&int每次x.iter()的迭代产生,取消引用它({{ 1}}),复制该值(因为&满足int,如果您尝试使用非Copy类型,如Copy它将无法编译,并且放置它在可变变量Stringi)中。也就是说,它相当于mut i。这样做的结果是for i in x.iter() { let mut i = *i; … }实际上只是递增局部变量而对矢量没有影响。您可以使用生成i += 1而不是&mut int的{​​{3}}并将&int模式更改为&mut ii来解决此问题。至i += 1,意为“更改*i += 1内的int

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

    那么:

    &str