function - 在闭包内调用堆上函数参数

标签 function rust rust-0.8

我使用的是 rust 0.8。

为什么我可以这样做:

fn add(num: ~int) -> ~fn(int) -> int { |x|
    *num + x
}

但不是这个:

fn outer(num: ~int) -> ~fn(int) -> int { |x|
    *inner(num) + x
}

fn inner(num: ~int) -> ~int {
    num
}

第二个失败,“错误:无法移出堆闭包中捕获的外部变量”。调用函数有什么特别之处?

是否担心内部函数可能会对静态分析无法捕获的装箱函数做一些肮脏的事情?

最佳答案

问题是调用闭包两次的可能性。在第一次运行时,捕获的变量 num 被移入 inner,即移出闭包的环境。然后,在第二次调用时,num 所在的位置现在无效(因为它已被移出),这破坏了内存安全。

更详细地说,可以将闭包视为(大约)

struct Closure { // stores all the captured variables
    num: ~int
}

impl Closure {
    fn call(&self, x: int) -> int { 
        // valid:
        *self.num + x

        // invalid:
        // *inner(self.num) + x
    }
}

希望这能让它更清楚:在无效的一个中,一个人试图将 self.num 从借用的指针后面移出到 inner 调用中(之后它与 num 字段完全断开)。如果这是可能的,那么 self 将处于无效状态,因为,例如,self.num 上的析构函数可能已被调用以释放内存(违反内存安全)。


对此的一个解决方案是“一次函数”,它被实现但隐藏在编译器标志后面,因为它们可能会被删除以支持(在最基本的情况下)调整调用的类型上面是fn call(self, x: int),也就是说,调用闭包会移动self,这意味着你可以移出环境(因为 call 然后拥有 self 及其字段)并且还意味着该函数静态保证只被调用一次*。

*如果闭包的环境不移动所有权,则严格来说不正确,例如如果它是 struct Env { x: int }

关于function - 在闭包内调用堆上函数参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19499387/

相关文章:

rust - 如何运行多个并行调用 thread::sleep 的 future ?

rust - 如何在 Rust 中 for_each 然后对它们进行计数?

arrays - 如何从函数返回拥有的数组?

c - main函数返回值错误?

javascript - JQuery/JavaScript中的回调

Javascript添加文件输入框按钮麻烦

javascript - 如何向 CSS 选择器添加通配符?

rust - 如何按插入顺序对 map 进行排序?