我可以创建一个"不安全的关闭"?

时间:2015-01-02 18:19:20

标签: closures rust

我有一些代码,简化后看起来像:

fn foo() -> Vec<u8> {
    unsafe {
        unsafe_iterator().map(|n| wrap_element(n)).collect()
    }
}

如果基础数据发生更改,迭代器将返回无效的项目。可悲的是,我无法依赖mut这里正常的Rust机制(我正在做一些......奇怪的事情)。

为了纠正不安全因素,我一次遍历迭代器并复制每个项目(通过wrap_element),然后将其全部放入Vec。这是有效的,因为没有其他机会进入并修改基础数据。

代码现在按原样运行,但由于我几次使用这个习惯用法,我想稍微干掉我的代码:

fn zap<F>(f: F) -> Vec<u8>
    where F: FnOnce() -> UnsafeIter
{
    f().map(|n| wrap_element(n)).collect()
}

fn foo() -> Vec<u8> {
    zap(|| unsafe { unsafe_iterator() }) // Unsafe block
}

我对此解决方案的问题是,对unsafe_iterator的调用是不安全的,wrap_element / collect使其再次安全。代码的结构方式根本不能表达出来。

我想以某种方式将我的封闭标记为unsafe,然后zap有责任使其再次安全。

1 个答案:

答案 0 :(得分:2)

无法以与unsafe相同的方式创建unsafe fn闭包,因为闭包只是匿名类型,具有Fn的实现,{{1 }和/或FnMut一系列特征。由于这些特征没有FnOnce方法,因此无法创建unsafe来调用的闭包。

您可以使用unsafe方法创建第二组闭包特征,然后为这些方法编写实现,但是您将失去大部分闭合糖。