我有一些代码,简化后,看起来像:
fn foo() -> Vec<u8> {
unsafe {
unsafe_iterator().map(|n| wrap_element(n)).collect()
}
}
如果基础数据发生更改,迭代器将返回无效的项目.可悲的是,我无法依赖正常的mut机制(我正在做一些……奇怪的事情).
为了纠正不安全因素,我一次遍历迭代器并复制每个项目(通过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使它再次安全.代码的结构方式根本不能表达出来.
我想以某种方式标记我的封闭是不安全的,然后它的责任是让它再次安全.
最佳答案 不可能与不安全的fn一样创建一个不安全的闭包,因为闭包只是匿名类型,具有Fn,FnMut和/或FnOnce系列特征.由于这些特征没有不安全的方法,因此无法创建一个不安全的调用闭包.
您可以使用不安全的方法创建第二组闭包特征,然后为这些特征编写实现,但是您将失去大部分闭合糖.