julia - 为什么 Julia 闭包不复制数组?

基于 Julia 在定义闭包时不复制数组这一事实,我刚刚在我的程序中发现了一个讨厌的错误。这使得连续编程变得困难。选择此设计的动机是什么?

对于将我的关闭状态与程序状态分离有什么建议吗?

举个例子

l = [2 1; 0 0];
f = x -> l[2,2];

那么 f(1) = 0 但如果你改变 l[2,2] = 1,那么 f(1) = 1。

最佳答案

您认为这是一个“关闭”的假设不成立。 l 此时在匿名函数的上下文中不是“封闭”变量。它只是对从“外部”作用域继承的变量的引用(因为它没有在匿名函数内部重新定义)。

这是一个真实闭包的例子:

f = let l=[2 1;0 0]
  x -> l[2,2];
end

变量 l 现在是 let block 的局部变量,而不是出现在全局范围内。 f 仍然可以访问它,即使它在技术上已经超出了范围。这就是闭包的意思。

由于 l 已经超出范围,它不再可以访问,除非通过 f ,这是一个闭包,可以将其作为封闭变量访问。


附言。我将在这里冒险并假设您所期望的是类似 matlab 的行为。与 matlab 的最大区别在于,当您在那里定义匿名函数句柄时,它会通过复制所有变量并使它们成为函数“对象”的一部分来捕获工作区的当前状态。您可以使用 functions 命令确认这一点。 Matlab 没有像 julia 一样的引用。这是 julia 的优点,而不是缺点,因为它允许用户使用优化来避免重新分配内存,而这在 matlab* 中更难实现。

* 虽然公平地说,matlab 在其他方面也很出色,通过尝试为您优化它


编辑: Liso 在评论中指出了一个非常重要的陷阱。假设 l 已经存在于全局工作空间中,我们输入

let l=l

虽然这是完全有效的语法,使 l 成为 let block 的局部变量,但它仍然被简单地初始化为 reference全局 l。因此,对全局 l 的任何更改仍将影响闭包,这不是您想要的。在这种情况下,您应该尝试通过制作复制(或深层复制,取决于您的用例)来“模仿”matlab 行为,这样局部变量就真正独立于其他任何东西一次它超出范围并变为“关闭”,即

let l = deepcopy(l)

此外,为了完整起见,当在 julia 中创建闭包时,值得指出它是如何在幕后实现的:生成的 f 函数只是一个可调用对象,包含一个字段它需要注意的每个“封闭”变量;您甚至可以通过 f.l 访问它。

https://stackoverflow.com/questions/46612475/

相关文章:

c# - 蓝牙扫描C#

php - 使用 Laravel 5.2 集合中的列名获取唯一值的计数

Python 2.7 - 如何检查是否按下了 SHIFT-Key 或 CTRL+Key?

r - 在 R 中制作特定的分位数图

sql - Oracle SQL - 从给定的字符串形成一个虚拟表以与另一个表连接

java - 使用 AssertJ,如何对列表的内容执行复杂的断言?

php - 使用 symfony 文件系统代替原生 PHP 的优势

python - urllib3 如何查找 Http 错误的代码和消息

wpf - 字符串格式正值和负值以及条件颜色格式 XAML

r - dplyr 中未显示 SD 值