代码之家  ›  专栏  ›  技术社区  ›  Moebius

为什么我不能保留一个盒子?

  •  2
  • Moebius  · 技术社区  · 9 年前

    考虑以下代码( 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 ,我将所有权授予此函数,但在 是(_E) 该函数不再需要所有权。它是一种不可变(只读)的所有权转移,因此我们确信当 main 克制 integer ->用回去似乎很安全。

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

    2 回复  |  直到 9 年前
        1
  •  6
  •   Shepmaster Lukas Kalbertodt    9 年前

    当我打电话时 is_even ,我将所有权授予此功能

    确切地您已转让所有权。你不再需要它了,这个函数可以为所欲为。在这种情况下,它将释放内存,因此您 肯定 通话后无法使用。

    该功能不再需要所有权

    这就是它被丢弃的原因。

    它是不可变的(只读)所有权转移

    这是不存在的。如果你完全转让所有权,就不会半途而废。

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

    实际上,我们 是肯定的 它被释放了,这是一件非常好的事情。Rust为我们解决了这一问题,所以你永远不必问“谁应该解放这个?”

    那么你怎么解决它呢?这很简单:传递对内部值的引用,而不是整个框。这 借,借 值(可变或不可变,由您决定)和所有权不会转移。

    fn is_even(nbr: &i32) -> bool { ... }
    
        2
  •  4
  •   Ben S    9 年前

    如果你想保留你的箱子的所有权,那么你必须 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);
    }
    

    请注意 是(_E) 现在引用(带有 & )到Box,我们必须传入一个引用(同样 & )当我们调用函数时。最后,该函数现在对引用而不是值进行操作,因此我们需要添加另一个 * 在我们对其进行操作之前取消引用它。

    然而,避免对拥有其内容的值(例如 String Vec Box ). 该函数可以改写为:

    fn is_even(nbr: &i32) -> bool {
        *nbr % 2 == 0
    }
    

    这适用于 任何 对整数的引用,而不仅仅是 锿。