为什么我不能挡住一个盒子?

时间:2015-09-02 12:02:03

标签: rust borrow-checker

考虑以下代码(on playground):

// calling this function move the ownership of nbr to is_even
// at the end of the function is_even doesn't give the ownership back
fn is_even(nbr: Box<i32>) -> bool {
    *nbr % 2 == 0
}

fn main() {
    let integer = Box::new(42);
    if is_even(integer) {
        print!("is even ");
    }
    println!("{}", integer);
}

我收到以下错误消息:

example.rs:10:17: 10:24 error: use of moved value: `integer` [E0382]
example.rs:10   println!("{}", integer);

example.rs:7:13: 7:20 note: `integer` moved here because it has type `Box<i32>`, which is non-copyable
example.rs:7    if is_even(integer) {

我不明白为什么。好的,当我致电is_even时,我会将此权限授予此功能,但在is_even结束时,该功能不再需要所有权。这是一项不可变(只读)的所有权转让,因此我们确信在main暂停integer时,我们不会将其删除 - &gt;使用它似乎是安全的。

仍然存在此错误。为什么以及解决方法是什么?

2 个答案:

答案 0 :(得分:6)

  

当我致电is_even时,我将此权限授予此功能

完全。您已转让所有权。你不再拥有它,而且这个功能会做你想要的。在这种情况下,它将释放内存,因此肯定在通话后无法使用它。

  

该功能不再需要所有权

这就是它被删除的原因。

  

这是一种不可变的(只读)所有权转移

那不存在。你完全转让了所有权,没有一半关于它。

  

所以我们确定它没有被删除

实际上,我们确定它已被释放,这是一件非常好的事情。 Rust为我们管理这个问题,所以你永远不必问问谁应该释放这个?&#34;

那么你如何解决它?这很简单:传递对内部值的引用,而不是整个框。这个借用值(可变或不同,取决于你)并且不转让所有权。

fn is_even(nbr: &i32) -> bool { ... }

答案 1 :(得分:4)

如果您想保留您的信箱的所有权,那么您必须pluck 借用,而不是取得它的所有权。这是您的代码的工作版本:

is_even

请注意,// calling this function move the ownership of nbr to is_even // at the end of the function is_even doesn't give the ownership back fn is_even(nbr: &Box<i32>) -> bool { **nbr % 2 == 0 } fn main() { let integer = Box::new(42); if is_even(&integer) { print!("is even "); } println!("{}", integer); } 现在需要对Box进行引用(带有is_even),当我们调用时,我们必须传入引用(再次使用&)功能。最后,函数现在对引用而不是值进行操作,因此我们需要添加另一个&来取消引用它,然后才能对其进行操作。

但是,避免对拥有其内容的值(例如*StringVec)使用非可变引用是一个很好的经验法则。该函数可以重写为:

Box

这适用于任何对整数的引用,而不仅仅是fn is_even(nbr: &i32) -> bool { *nbr % 2 == 0 } es中的。