Is it possible to force a nested function definition to not be a closure?
是否有一个修饰符可以放在一个函数声明上,强制它不成为一个闭包?我希望下面的代码不要在对inner进行这种假定的修改的情况下编译:
1 2 3 4 5
| let outer() =
let i = 7
let inner() =
printf"%i" i
inner() |
但是对i的抱怨还没有定义。这样做的原因是安全性——我想确保我不会捕获或者在不捕获的时候修改任何东西,以及闭包与函数的性能。
- 我怀疑唯一可能的答案是使inner成为仅包含outer的模块中的私有顶级功能。
- @约翰帕尔默是的,那是显而易见的。我更喜欢内联定义的布局,尤其是当outer是一种方法时。
- 我认为不必担心修改数据的正确解决方案是只使用不可变的变量和类型。
- @由于性能原因,svick不可能使每个变量和类型都不可变。即使是这样,我仍然想确保我没有因为开销而不需要关闭的地方。
- 您担心的开销是否会导致您错过特定的端到端性能目标?如果没有,那么这是一个过早优化的情况。参见EricLippert关于如何在这里(这里,这里,这里,等等)考虑优化的出色描述。
- @kvb不,它没有让我错过任何目标(我正在写我的第一个f应用程序,所以还没有错过或实现任何目标!)我想这是不可能的?当我想到一个使用自包含函数的算法时,我相信这是一个好主意,它能够告诉编译器并让它验证这一点。
- 我认为这不可能,但我也不认为值得担心。我写了很多F代码,无意中捕获从来都不是问题。正如@svick所说,在可行的情况下,您应该使用不可变性,并且应该首先瞄准正确性。在性能敏感的代码中,您可能会发现(在分析之后!)你需要重新排序定义,否则只需按照看起来最自然的顺序来写东西。
- @我只同意一个警告。我想做的是增加而不是减少正确性和表达性!如果你能写(比如说)let pure inner() = ...,它会立即告诉读者,没有必要向上看定义来理解它的作用。这不会是过早的优化,根据定义,这会降低正确性和/或清晰度。
- 注意,在您的特定情况下,编译器在发布模式下通过嵌入i来优化闭包。F编译器在发布模式下执行了许多其他优化。除了@kvb的评论,这也是不"先发制人"担心性能的另一个原因。
除了将函数移动到没有范围可捕获的位置之外,没有办法实现这一点。也就是说,在您给出的示例中,有一种简单的方法可以部分实现这一点:
1 2 3 4 5
| let outer() =
let inner() =
printf"%i" i
let i = 7
inner() |