MATLAB中匿名函数如何调用自身

6

作为一个实验(因为我正在从用户数据生成匿名函数),我运行了以下MATLAB代码:

h = @(x) x * x
    h = @(x) x * x
h(3)
    ans = 9
h = @(x) h(x) + 1
    h = @(x)h(x)+1
h(3)
    ans = 10

基本上,我让一个匿名函数调用自身。 MATLAB记住了旧函数定义,而不是递归地执行。然而,工作空间不会将其显示为变量之一,句柄也似乎不知道它。只要保留新的函数,旧函数是否会被存储在后台?这种构造有什么“陷阱”吗?

我认为设计本身就是一个“坑”和一个不好的主意,因为它非常不直观,会将很多东西隐藏在代码中,让其他人看起来难以理解。 - tmpearce
1个回答

8

匿名函数会记住定义时工作区的相关部分,并复制它。因此,如果您在匿名函数的定义中包含一个变量,并且稍后更改该变量,它将在匿名函数内保留旧值。

>> a=1;
>> h=@(x)x+a %# define an anonymous function
h = 
    @(x)x+a
>> h(1)
ans =
     2
>> a=2 %# change the variable
a =
     2
>> h(1)
ans =
     2 %# the anonymous function does not change
>> g = @()length(whos)
g = 
    @()length(whos)
>> g()
ans =
     0 %# the workspace copy of the anonymous function is empty
>> g = @()length(whos)+a
g = 
    @()length(whos)+a
>> g()
ans =
     3 %# now, there is something in the workspace (a is 2)
>> g = @()length(whos)+a*0
g = 
    @()length(whos)+a*0
>> g()
ans =
     1 %# matlab doesn't care whether it is necessary to remember the variable
>> 

这是否意味着我不应该在处理大矩阵时使用匿名函数,特别是如果内存是一个问题?具有常量的匿名函数是否像带参数的函数一样工作,只有在更改内容时才会进行复制? - Andrew
2
@AndrewPiliser:我认为写时复制也适用于匿名函数,即只要您不更改a的值,就可以正常运行。 编辑:刚刚测试了一下。是的,它是写时复制。 - Jonas
1
+1 FYI,我认为匿名函数捕获的不仅是工作区的“相关部分”的副本,而是在处理创建时整个工作区。至少在早期的Matlab版本中是这样的。(eval的存在意味着Matlab不能在解析时知道什么是相关的。)嵌套函数对它们关闭的活动变量也是这样工作的。您可以在函数句柄上使用info = functions(h)来查看它捕获了什么,或者在调试器中检查它。 - Andrew Janke

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接