问题描述
下面的代码没有通过借用检查器,因为 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 );
}
}
}