Jam*_*ell 15 unsafe rust borrow-checker
我遇到了 Rust 借用检查器错误,我认为这是当前非词法生命周期实现的限制。我想写的代码看起来像这样:
struct Thing {
value: i32
}
impl Thing {
fn value(&self) -> &i32 {
&self.value
}
fn increment(&mut self) {
self.value += 1;
}
}
/// Increments the value of `thing` if it is odd, and returns a reference to the value.
fn increment_if_odd(thing: &mut Thing) -> &i32 {
let ref_to_value = thing.value();
if (*ref_to_value % 2) == 0 {
return ref_to_value;
}
thing.increment(); // fails to compile because the immutable borrow `ref_to_value` is still alive
thing.value()
}
Run Code Online (Sandbox Code Playgroud)
第一个问题:我认为这段代码是 100% 安全并且借用检查器过于保守的想法是否正确?返回的分支ref_to_value
不会发生变化thing
,因此保证引用有效,而另一个分支ref_to_value
根本不使用。(我知道如果我return ref_to_value;
用return thing.value();
它替换就会编译,但在我的实际代码中该value
方法很昂贵。)
看来我可以通过指针“清洗”引用来解决这个问题:
if (*ref_to_value % 2) == 0 {
return unsafe {
&*(ref_to_value as *const i32)
}
}
Run Code Online (Sandbox Code Playgroud)
第二个问题:这安全吗?我以前从未使用过 unsafe 所以我很紧张。
我猜第三个问题:有没有办法用安全的 Rust 重写它?限制是value
只能在非变异路径上调用一次。
kal*_*ave -4
可能是安全的,还没仔细观察过。另一方面,您可以将该函数重写为:
fn increment_if_odd(thing: &mut Thing) -> &i32 {
if (*thing.value() % 2) != 0 {
thing.increment();
}
thing.value()
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
617 次 |
最近记录: |