2016-11-17 57 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是否编译代码? –