2014-10-07 112 views
5

所以,我是applying for a job,需要弄清楚how nested functions work。更具體地說,我想知道gnovice發佈的以下示例是如何工作的。嵌套函數在MATLAB中如何工作?

的問題是:

考慮下面的函數,將輸出在命令窗口中輸入下面的代碼時會是什麼?

function fcnHandle = counter 
    value = 0; 
    function currentValue = increment 
    value = value+1; 
    currentValue = value; 
    end 
    fcnHandle = @increment; 
end 

f1 = counter(); 
f2 = counter(); 
output = [f1() f1() f2() f1() f2()]; %# WHAT IS IT?! 

我不是找工作,我能回答弄清楚這個問題。我還發現the answerMohsenthis question直觀(找到矩陣的大小而不調用內置函數)。但是,我忍不住聽到了阿爾伯特愛因斯坦的聲音。

enter image description here

我覺得documentation有點亂亂的,所以我會非常高興,如果有人能夠解釋它是如何工作的。

+2

+1在聽到你的頭! :-) – 2014-10-07 15:09:32

回答

4

讓我試試....

每當函數counter()其所謂創建一個獨特的功能句柄。該函數句柄是一個函數的句柄,該函數被稱爲增量,它使用自己的變量值並將其加1。

因此,如果調用兩次,就像在代碼(f1,f2)中一樣,每次都會返回相同的函數(增量)但不同的句柄。你有TWICE定義的功能。他們每個人現在都獨立工作。由於這個特定函數(增量)依賴於保存的計算內部值,因此您可以觀察如果在您的代碼示例中調用,輸出[1 2 1 3 2]。

seing更好的差異的一個好方法是重新定義功能:

function fcnHandle = counter(val) 
    value = val; 
    function currentValue = increment 
    value = value+1; 
    currentValue = value; 
    end 
    fcnHandle = @increment; 
end 

,把它想:

>> f1 = counter(0); 
>> f2 = counter(1000); 
>> output = [f1() f1() f2() f1() f2()] %# WHAT IS IT? 

現在,你會看到,輸出是[1 2 1001 3 1002]

現在更有意義了嗎?

創建此代碼是爲了利用函數句柄的這個屬性(它是相同的事物,但它被複制了兩次)。

2

整齊的練習。我從來沒有使用嵌套函數與手柄,所以這裏是我的思維過程: 我發現這個段落the manual很有啓發:

嵌套函數可以使用變量有三個來源:

Input arguments 

Variables defined within the nested function 

Variables defined in a parent function, also called externally scoped variables 

當你爲嵌套函數創建一個函數句柄,該句柄處理 不僅存儲該函數的名稱,而且還存儲 外部作用域變量的值。

因此在本例中,counter將變量value0然後調用increment功能。 increment商店value在其句柄中,因此每次調用increment時,value都會增加並覆蓋value=0的第一個定義。

因此,輸出爲0加上調用次數爲increment的次數,每次調用counter的給定實例。

當你這樣寫:

f1 = counter(); 
f2 = counter(); 

創建功能counter這將增加獨立的兩個單獨的實例。

3

使用的嵌套函數是相關的記憶化(額外讀數參見:use nested functions to memoize costly functions),因爲它利用parametric function handles其存儲在創建的參數的值。

有您需要注意兩件事情:

  1. counter()返回函數直接處理到嵌套函數

    f1 = counter() 
    f1 = 
        @counter/increment 
    
  2. 嵌套函數將「拯救」的範圍變量。詳情請參閱functions()

    s = functions(f1) 
    s = 
        function: 'counter/increment' 
         type: 'nested' 
         file: '\\ic.ac.uk\homes\ok1011\MATLAB\counter.m' 
        workspace: {[1x1 struct]} 
    

    與作用域工作區保持:

    s.workspace{1} 
    ans = 
        fcnHandle: @counter/increment 
         value: 0 
    

基本上,counter()初始化value到零,並@counter/increment連續調用將執行value = value+1;

最後,@counter/increment被分配到f1和所有f1()正在做的是@counter/increment()對以前初始化value。初始化f2 = counter(),創建另一個計數器,並單獨保存workspace

+0

我更喜歡這個解釋。它顯示了實際內容。 +1。 – rayryeng 2017-09-13 18:01:21