Memory 移动和返回可变指针

Memory 移动和返回可变指针,memory,rust,ownership,Memory,Rust,Ownership,我正在学习Rust教程,并试图解决此问题: 实现一个函数incrementMut,该函数以整数向量作为输入,并通过将每个值递增一来修改原始列表的值 这似乎是一个相当简单的问题,是吗 我一直在尝试一个解决方案来编译,现在我开始失去希望。这就是我到目前为止所做的: fn main() { let mut p = vec![1i, 2i, 3i]; increment_mut(p); for &x in p.iter() { print!("{} ",

我正在学习Rust教程,并试图解决此问题:

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

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

我一直在尝试一个解决方案来编译,现在我开始失去希望。这就是我到目前为止所做的:

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

我觉得我在Rust中缺少了一些关于内存所有权的核心概念,这使得解决像这样的琐碎问题变得非常困难,有人能解释一下吗?

您的代码中有一些错误

increment_mut&p,如果p是Vec,则需要函数increment_mut&Vec&-引用和&mut引用在语法上是完全不同的,如果你想要一个&mut引用,你必须写&mutp,而不是&p

您需要了解模式及其操作方式;对于x.iter中的&mut i,它不会执行您希望它执行的操作:它将执行x.iter每次迭代生成的&int,将其解引用为&,复制值,因为int满足Copy,如果您使用非复制类型(如字符串)尝试它,它将不会编译,并将其放置在可变变量i mut i中。也就是说,它等价于x.iter{let mut i=*i;…}中的for i。这样做的效果是i+=1实际上只是增加一个局部变量,对向量没有影响。您可以通过使用生成&mut int而不是&int,并将&mut i模式更改为just i,将i+=1更改为*i+=1,这意味着“更改&mut int中的int”

通过调用向量,您还可以从使用&mut-Vec切换到使用&mut[int]。这是一种更好的做法;您实际上不应该需要对向量的引用,因为这需要两个级别的间接寻址,其中只需要一个。对于&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;
    }
}

您的代码中有一些错误

increment_mut&p,如果p是Vec,则需要函数increment_mut&Vec;&-references和&mut references在语法上是完全不同的,如果想要&mut引用,则必须编写&mut p,而不是&p

您需要了解模式及其操作方式;对于x.iter中的&mut i,它不会做您希望它做的事情:它将做的是获取x.iter每次迭代生成的&int,将其解引用为&,复制值,因为int满足Copy,如果您使用非复制类型(如字符串)尝试它,它将不会编译,并将其放置在muta中可变变量i mut i。也就是说,它等价于x.iter{let mut i=*i;…}。这样做的效果是,i+=1实际上只是增加一个局部变量,对向量没有影响。您可以通过使用来解决这个问题,它生成&mut int而不是&int,并将&mut i模式更改为just i,将i+=1更改为*i+=1,这意味着“在&mut int中更改int”

通过调用向量,您还可以从使用&mut-Vec切换到使用&mut[int]。这是一种更好的做法;您实际上不应该需要对向量的引用,因为这需要两个级别的间接寻址,其中只需要一个。对于&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;
    }
}

请记住,这组注释是为一个大约有一年历史的Rust版本编写的,这个版本对于Rust来说非常古老。毫无疑问,您会注意到各种不同之处。是否有什么地方可以推荐优秀的Rust教程,而不是?有些教程甚至似乎已经过时,链接是针对0.9的,如URL版本eals。从开始,你会很好,获得最新的信息。请记住,这组注释是针对一个大约一年前的版本,这对于生锈来说是非常古老的。毫无疑问,你会注意到各种不同之处。除了上的一些教程之外,还有什么地方可以推荐好的生锈教程吗正如URL显示的那样,0.9版的链接似乎已经过时了。从开始,你就可以获得最新的信息。
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.
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;
    }
}