【问题标题】:Can I create an "unsafe closure"?我可以创建一个“不安全的关闭”吗?
【发布时间】:2015-03-01 01:13:04
【问题描述】:

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

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,然后zaps 有责任让它再次安全。

【问题讨论】:

    标签: closures rust


    【解决方案1】:

    不可能像unsafe fn一样创建unsafe闭包,因为闭包只是匿名类型,实现了FnFnMut和/或FnOnce系列特征.由于这些特征没有 unsafe 方法,因此无法创建要调用的 unsafe 闭包。

    您可以使用unsafe 方法创建第二组闭包特征,然后为它们编写实现,但您会丢失很多闭包糖。

    【讨论】:

    • 创建一组新的特征是一个有趣的想法!我认为糖化与编译器密切相关,作为最终用户,我无法做任何事情来窃取它以获得新特性?
    • 你也许可以做一些事情,比如为旧特征实现新特征,然后你会得到从闭包语法到不安全特征的隐式“转换”。你仍然不会得到函数调用语法,但我认为这是一个很好的权衡。
    • I gave that a shot,但它并没有它本来应该的那么有用。问题是当我们在闭包中“调用”不安全的 fn 时编译器仍然会报错,因为它不知道 unsafe 会被传递,所以没有机会使用糖。
    猜你喜欢
    • 2021-11-12
    • 2012-11-17
    • 2018-12-05
    • 1970-01-01
    • 2016-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多