gpt4 book ai didi

arrays - 索引对象点表示法给出标量属性

转载 作者:太空宇宙 更新时间:2023-11-03 19:11:13 25 4
gpt4 key购买 nike

在使用点表示法应用方法后尝试引用对象属性时,我遇到了一个问题。它仅在我尝试索引初始对象时发生

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;

当调用整个数组并收集属性数据时它工作正常

[A.procData.data]

如果我尝试对 A 进行索引,那么我只会得到一个标量

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

即使没有属性调用似乎也能正常工作

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

有什么想法吗?

最佳答案

我肯定会称这是解析器中的错误;一个错误,因为它一开始并没有抛出错误,而是允许您首先编写:obj.method.prop!

MATLAB 在这种语法的某些变体中崩溃是一个严重的错误,绝对应该是 reported。到 MathWorks。

现在 MATLAB 中的一般规则是您不应该直接“索引到结果”。相反,您应该首先将结果保存到一个变量中,然后索引到该变量中。

如果您使用 func(obj) 而不是 obj.func() 来调用对象的成员方法 ( dot-notation vs. function notation ),这个事实就很清楚了:

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

相反,如您所述,您应该使用:

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

FWIW,这也是使用普通结构和常规函数(与 OOP 对象和成员函数相对)时发生的情况,因为您无论如何都无法索引到函数调用的结果。示例:

% 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

然后所有以下调用都会抛出错误(它们应该如此):

% 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 不允许对函数调用进行索引(无需引入临时变量)是有充分理由的,无论是点索引还是下标索引。

以下面的函数为例:

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

如果我们允许对函数调用进行索引,那么在如何解释以下调用 f(4) 时就会出现歧义:

  • 是否应该解释为:f()(4)(即不带参数的调用函数,然后使用线性索引对结果矩阵进行索引以获得第 4 个元素)
  • 或者它应该解释为:f(4)(调用一个参数为 n=4 的函数,并返回矩阵 magic(4))<

这种混淆是由 MATLAB 语法中的几件事引起的:

  • 它允许仅通过名称调用不带参数的函数,而无需括号。如果有函数 f.m,您可以将其称为 ff()。这使得解析 M 代码更加困难,因为不清楚标记是变量还是函数。

  • 括号用于矩阵索引和函数调用。因此,如果标记 x 表示一个变量,我们使用语法 x(1,2) 作为矩阵的索引。同时如果x是一个函数名,那么x(1,2)用于调用带有两个参数的函数。

    <

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

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

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

我们应该从 MAX 返回每个输出变量的第 4 个元素,还是仅从第一个输出参数返回第 4 个元素以及完整的第二个输出?当函数返回不同大小的输出时怎么办?

所有这些仍然适用于其他类型的索引:f()(3)/f(3), f().x/f.x, f(){3}/f{3}.

因此,MathWorks 决定避免上述所有混淆,并且根本不允许直接对结果进行索引。不幸的是,他们在这个过程中限制了语法。例如 Octave 没有这样的限制(你可以写 magic(4)(1,2)),但是新的 OOP 系统仍然在开发中,所以我不了解 Octave 如何处理此类情况。


对于那些感兴趣的人,这让我想起了另一个 similar bug关于包和类并直接索引以获取属性。无论您是从命令提示符、脚本还是 M 文件函数调用它,结果都是不同的...

关于arrays - 索引对象点表示法给出标量属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17515941/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com