2012-06-26 50 views
6

作爲一個實驗(和因爲我生成匿名函數關的用戶數據)我跑以下MATLAB代碼:匿名函數自稱在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不是以遞歸方式進行操作,而是記住了舊的函數定義。但是,工作區並未將其顯示爲變量之一,並且該句柄似乎也不知道它。

只要保留新功能,舊功能是否會存儲在幕後?這種建築有沒有什麼「陷阱」?

+0

我要說的是,設計全部由自己是個「疑難雜症」和一個壞主意,因爲它是非常不直觀,並隱藏其他人查看代碼這麼多。 – tmpearce

回答

8

匿名函數會在定義時記住工作區的相關部分,並將其複製一份。因此,如果您在匿名函數的定義中包含一個變量,並稍後更改該變量,則它會將舊值保留在匿名函數中。

>> a=1; 
>> [email protected](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 
>> 
+0

那麼這是否意味着我不想使用大型矩陣的匿名函數,特別是如果內存是一個問題?使用常量的匿名函數的作用就像帶有參數的函數一樣,當事情發生變化時,它們只會複製一份。 –

+2

@AndrewPiliser:我會假設copy-on-write也適用於匿名函數,也就是說,只要你不改變'a'的值,你就會沒事的。 **編輯**:只是測試它。是的,它是複製寫入。 – Jonas

+1

+1僅供參考,我認爲匿名函數不僅捕獲工作空間的「相關部分」的副本,還捕獲創建句柄時的整個工作空間。至少在早期的Matlab版本中。 (「eval」的存在意味着Matlab不一定能夠在解析時知道什麼是相關的。)嵌套函數以這種方式工作,而它們關閉的活動變量。您可以在函數句柄上使用'info = functions(h)'來查看它捕獲的內容,或者在調試器中檢查它。 –