2016-11-17 43 views
3

我定義下面的類無法使用功能輸入;

classdef TimerManager < handle 

methods (Access = private) 
    function obj = TimerManager() 
    end 
end 

methods (Static) 
    function singleObj = getInstance(varargin) 
     varargin{1} 
     singleObj = TimerManager(); 
    end 
end 

methods 
    function foo(obj) 
    end 

end 

end 

我發現下面的代碼的工作方式不同瓦特/或W/O; 這是預期的嗎?或者我錯過了什麼?

>> TimerManager.getInstance(0).foo() 

ans = 

0 

>> TimerManager.getInstance(0).foo(); 
Index exceeds matrix dimensions. 

Error in TimerManager.getInstance (line 13) 
     varargin{1} 

如果我在邊getInstance中使用nargin,如果我放置它是0;最後。

+0

有趣的是,它可以在Octave v4.0.3(Ubuntu)下運行。 – stephematician

+0

我在兩種情況下都出現錯誤。什麼版本的MATLAB?另外'foo'不應該返回一個值,那麼你如何得到'0'? – Suever

回答

3

您的錯誤與分號無關。這與MATLAB處理對象的下標引用的方式(subsref)有關。

的(詳細)問題

在MATLAB中,你不能 「鏈」 下標引用。例如,如果我們創建一個單元陣列,我們不能立即索引到該單元陣列而無需首先將其分配給一個臨時變量:

X1 = {'X1', 'X2', 'X3'}{1} 

Error: Unbalanced or unexpected parenthesis or bracket.

這同樣適用於訪問對象的屬性或方法這是由函數返回的。在你的情況下,TimerManager.getInstance返回一個實例,你必須首先分配給一個臨時變量,然後才能訪問它的foo方法。

instance = TimerManager.getInstance(0); 
fooResult = instance.foo(); 

MATLAB做出嘗試拋出一個錯誤或警告,當它認爲你想一起爲「鏈」,這些標引用,但如果有這樣一個場景,下標操作的順序是有效的,那麼它無法拋出相應的錯誤。您正在遇到其中一種情況。

您正在使用的語法類似如下:

a.b(c).d() 

這是有效的,如果a.bstructsd一個領域是一個函數處理數組。在這種情況下,c索引

當MATLAB解析它時,它將檢索a.b的值,然後確保c是一個正整數(一個有效索引)並且在數組a.b的範圍內。然後,一旦確認,MATLAB將訪問d字段並調用它。

如果我們回到您的代碼一秒鐘,我們可以註釋掉varargin{1}行並獲得更有用的錯誤消息。

TimerManager.getInstance(0).foo(); 

Subscript indices must either be real positive integers or logicals.

好了,所以那種有道理,MATLAB是治療TimerManager.getInstancestruct陣列,並試圖索引它與0這是在錯誤顯然無效和結果。

關於你的報道,注意上面,我說,應該struct陣列上應用下標引用之前,MATLAB首先要獲得的TimerManager.getInstance當前值實際錯誤。因爲MATLAB認爲這只是一個struct數組,它不會將任何輸入參數傳遞給它,這導致varargin爲空,並且您看到的錯誤。

所以你的說法是功能上是相同的:

instance = TimerManager.getInstance;  % No input arguments 
instance(0).foo()       % Indexing error 

注意,這確實工作,如果「輸入」到getInstance1,因爲這是一個有效的索引,1 x 1陣列TimerManager實例返回當您撥打Timermanager.getInstance時無輸入。

TimerManager.getInstance(1).foo(); 

可能的解決方案

使用一個臨時變量

instance = TimerManager.getInstance(0); 
fooResult = instance.foo(); 

或者使用method(obj)符號用於調用該方法,而不是obj.method()符號。

foo(TimerManager.getInstance(0)) 

註記上八度

無的,這是要在八度的問題,因爲它允許而不需要一個臨時變量「鏈」,這些標引用在一起。

+0

這聽起來是MATLAB的解析器不理解每個ID的語義......我想這是因爲它只解釋語言但不編譯語言。 Octave如何解決這個問題? Octave是否編譯代碼? –