Rust:如何告诉借用检查器移动取决于布尔值?

问题描述

下面的代码没有通过借用检查器,因为 Label-A 使用了一个被 Label-B 消耗的值,但代码实际上是安全的:Label-A 被 processed 保护,它只是设置是否运行 Label-B。

我如何告诉编译器依赖关系,或者如果我不能,解决这个问题的习惯用法是什么?

(使 X copy/Clone 不可接受,也不使 consume 取引用,Rc<X> 都没有吸引力(数据结构已经相当复杂))


struct X(i32);

fn consume1(_x: X) {
    ()
}

fn consume2(_x: X) {
    ()
}

fn predicate(_x: &X) -> bool {
    true
}

pub fn main() {
    let xs = vec![X(1),X(2)];
    
    for x in xs {
        let mut processed = false;

        // for _ in _ {
        if predicate(&x) {
            consume1(x); // Label-B
            processed = true;
        }
        // } end for
        // this for loop here is just to show that the real code
        // is more complicated,the consume1() is actually called
        // (somehow) inside this inner loop

        // some more code
        
        if !processed {
            consume2(x);  // Label-A
        }
    }
}

解决方法

除非我误解了,否则我认为对您来说最好的选择是使用“选项”。这样你也可以摆脱那个 boolean 标志。

struct X( i32 );

fn consume1( _x: X ) { }

fn consume2( _x: X ) { }

fn predicate( _x: &X ) -> bool {
    true
}

pub fn main( ) {
    let xs = vec![ Some( X( 1 ) ),Some( X( 2 ) ) ];

    for mut x in xs {
        if predicate( x.as_ref( ).unwrap( ) ) {
            consume1( x.take( ).unwrap( ) );
        }   
        if let Some( x ) = x {
            consume2( x );
        }
    }
 }