gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-29 07:55:06 25 4
gpt4 key购买 nike

我使用的是 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com