我想将someval分配给不安全调用的结果,并在以后使用someval:

fn partially_unsafe(item: *const scary_c_struct) -> i32 {
    let someval = item.as_ref();
    match someval {
        Some(big_long_block) => {
            //lots of lines of code
            42
        }
        None => -1,
    }
}

这不会编译,因为item.as_ref()必须位于unsafe块中:
fn partially_unsafe(item: *const scary_c_struct) -> i32 {
    unsafe {
        let someval = item.as_ref();
        match someval {
            Some(big_long_block) => {
                //lots of lines of code
                42
            }
            None => -1,
        }
    }
}

如果函数中还有很多其他嵌套块,这似乎很麻烦。

我可以使用此表达式,但这会破坏不变性:
// ...
let mut someval = None;
unsafe {
    someval = item.as_ref();
}
// ...

我也可以将item.as_ref()隐藏在其自己的函数中。

这些似乎都不令人满意。有没有较麻烦的方式来表达不安全的作业?

最佳答案

直接的答案是:延迟初始化

let someval;
unsafe {
    someval = item.as_ref();
}
// use someval

但是,这就是您真正想要的吗?
unsafe的丑陋真相是遍历,并且渗透到unsafe块的边界之外。

例如,上面允许:
let someval; // &T
unsafe {
    someval = &*(ptr::null() as *const T);
}

在这种情况下,崩溃很可能发生在unsafe块之外,即使它的起源在unsafe块之内。

因此,缩小unsafe块在这里适得其反;它引起了错误的安全感。

关于rust - 是否有一个习惯用法,可以为不安全的调用的结果分配一个var,以后再使用该var而不将其他所有内容嵌套在unsafe {}中?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45468755/

10-10 15:38