索引对象点符号方法提供了标量属性 [英] indexed object dot notation method gives scalar property

查看:109
本文介绍了索引对象点符号方法提供了标量属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我看到一个问题,当我尝试并具有使用点符号应用方法后引用一个对象的属性。
只当我尝试指数初始对象发生

I'm seeing an issue when I try and reference an object property after having used a dot notation to apply a method. it only occurs when I try to index the initial object

classdef myclassexample

properties
    data
end    

methods   
    function obj = procData(obj)            
        if numel(obj)>1
            for i = 1:numel(obj)
                obj(i) = obj(i).procData;
            end
            return
        end
        %do some processing
        obj.data = abs(obj.data);
    end
end
end

然后,指派以下

A = myclassexample;
A(1).data= - -1;
A(2).data =  -2;

调用整个阵列和收集它工作正常属性数据时

when calling the whole array and collecting the property data it works fine

[A.procData.data]

如果我尝试和索引,然后我只能得到一个标出来

if i try and index A then i only get a scalar out

[A([1 2]).procData.data]

虽然它似乎没有属性调用做精

even though it seems to do fine without the property call

B  = A([1 2]).procData;
[B.data]

什么想法?

推荐答案

我肯定会调用这个的解析器的bug;一个错误,因为它没有引发错误,首先,而是让你写的:<!code> obj.method.prop 首先

I would definitely call this a bug in the parser; A bug because it did not throw an error to begin with, and instead allowed you to write: obj.method.prop in the first place!

这在MATLAB这种语法的一些变化坠毁的事实是一个严重的错误,绝对应该是报道以MathWorks的。

The fact that MATLAB crashed in some variations of this syntax is a serious bug, and should definitely be reported to MathWorks.

现在在MATLAB一般的规则是,你不应该索引结果直接。相反,你应该先结果索引保存到一个变量,然后进入该变量。

Now the general rule in MATLAB is that you should not "index into a result" directly. Instead, you should first save the result into a variable, and then index into that variable.

这事实是清楚的,如果你使用的形式 FUNC(OBJ),而不是 obj.func()来调用的对象成员方法(点符号与函数符号

This fact is clear if you use the form func(obj) rather than obj.func() to invoke member methods for objects (dot-notation vs. function notation):

>> A = MyClass;
>> A.procData.data       % or A.procData().data
ans =
     []
>> procData(A).data
Undefined variable "procData" or class "procData". 

相反,正如你指出,你应该使用:

Instead, as you noted, you should use:

>> B = procData(A):    % or: B = A.pocData;
>> [B.data]


FWIW,这也与普通的结构和功能的定期工作时(相对于OOP对象和成员函数)会发生什么,因为你不能索引到一个函数调用的结果呢。例如:


FWIW, this is also what happens when working with plain structures and regular functions (as opposed to OOP objects and member functions), as you cannot index into the result of a function call anyway. Example:

% a function that works on structure scalar/arrays
function s = procStruct(s)
    if numel(s) > 1
        for i=1:numel(s)
            s(i) = procStruct(s(i));
        end
    else
        s.data = abs(s.data);
    end
end

然后,所有下面的调用将抛出错误(因为他们应该):

Then all the following calls will throw errors (as they should):

% 1x2 struct array
>> s = struct('data',{1 -2});

>> procStruct(s).data
Undefined variable "procStruct" or class "procStruct". 

>> procStruct(s([1 2])).data
Undefined variable "procStruct" or class "procStruct". 

>> feval('procStruct',s).data
Undefined variable "feval" or class "feval". 

>> f=@procStruct; f(s([1 2])).data
Improper index matrix reference. 


您可能会问自己,为什么他们决定不会允许这样的语法。那么它原来有一个很好的理由MATLAB不允许索引到一个函数调用(无需引入一个临时变量即是),无论是点索引或下标索引。


You might be asking yourself why they decided to not allow such syntax. Well it turns out there is a good reason why MATLAB does not allow indexing into a function call (without having to introduce a temporary variable that is), be it dot-indexing or subscript-indexing.

以下面的功能,例如:

function x = f(n)
    if nargin == 0, n=3; end
    x = magic(n);
end

如果我们允许索引到一个函数调用,那么将是如何跨$ P $磅以下调用 F(4)歧义:

If we allowed indexing into a function call, then there would be an ambiguity in how to interpret the following call f(4):


  • 它应该是PTED为跨$ P $ F()(4)(即使用线性索引不带参数调用函数,然后索引到结果矩阵获得第4单元)

  • 还是应际preTED为: F(4)(调用函数有一个参数为n = 4,并返回矩阵魔术(4)

  • should it be interpreted as: f()(4) (that is call function with no arguments, then index into the resulting matrix using linear indexing to get the 4th element)
  • or should it interpreted as: f(4) (call the function with one argument being n=4, and return the matrix magic(4))

这混乱是由几件事情在MATLAB语法造成的:

This confusion is caused by several things in the MATLAB syntax:


  • 它允许简单地通过他们的名字叫不带参数的功能,而不需要括号。如果有一个函数 FM ,你可以把它作为任何˚F F() 。这使得解析M- code更难,因为它是不明确的标记是否变量或函数。

  • it allows calling function with no arguments simply by their name, without requiring the parentheses. If there is a function f.m, you can call it as either f or f(). This makes parsing M-code harder, because it is not clear whether tokens are variables or functions.

括号用于两个矩阵索引以及函数调用。所以,如果一个标记 X 重新presents一个变量,我们使用语法 X(1,2)作为索引到基质。同时,如果 X 是函数的名称,然后 X(1,2)用来调用有两个参数的函数。

parentheses are used for both matrix indexing as well as function calls. So if a token x represents a variable, we use the syntax x(1,2) as indexing into the matrix. At the same time if x is the name of a function, then x(1,2) is used to call the function with two arguments.

混乱的另一点是逗号分隔的列表和函数返回多个输出。例如:

Another point of confusion is comma-separated lists and functions that return multiple outputs. Example:

>> [mx,idx] = max(magic(3))
mx =
     8     9     7
idx =
     1     3     2

>> [mx,idx] = max(magic(3))(4)     % now what?

我们应该从MAX,或第4单元只从第一输出参数与完整的第二输出一起返回每个输出变量的第4个元素?什么时候该函数返回不同大小的输出是什么?

Should we return the 4th element of each output variables from MAX, or 4th element from only the first output argument along with the full second output? What about when the function returns outputs of different sizes?

这一切都仍然适用于其他类型的索引: F()(3) / F(3) F()。X / FX F(){3} / ˚F{3}

All of this still applies to the other types of indexing: f()(3)/f(3), f().x/f.x, f(){3}/f{3}.

由于这个原因,MathWorks公司决定避免上述所有的混乱和根本不直接允许进行索引的结果。不幸的是他们限制在这个过程中的语法。八度例如有没有这样的限制(你可以写魔术(4)(1,2)),但随后又在新的OOP系统仍处于正在发展的过程,所以我不知道这样的情况下,如何八度的交易。

Because of this, MathWorks decided avoid all the above confusion and simply not allow directly indexing into results. Unfortunately they limited the syntax in the process. Octave for example has no such restriction (you can write magic(4)(1,2)), but then again the new OOP system is still in the process of being developed, so I don't know how Octave deals with such cases.

对于那些有兴趣,这让我想起另一个类似的错误的问候包和类,直接索引得到属性。结果是不同的,你是否在命令提示符下称它,从脚本,或从M-file函数...

For those interested, this reminds me of another similar bug with regards to packages and classes and directly indexing to get a property. The results were different whether you called it from the command prompt, from a script, or from a M-file function...

这篇关于索引对象点符号方法提供了标量属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆