对象可以用圆括号或花括号进行索引,例如
obj(idx)、obj{idx},甚至
obj(idx).field。然而,索引的实际含义由程序员来决定。以多项式类为例,
p(n) 可能表示多项式第 n 次幂的系数,也可能表示多项式在 n 处的求值结果。
这种下标引用的含义由 subsref 方法确定。
newval = subsref (val, idx) ¶根据 idx 指定的下标对 val 执行下标元素选择操作。
下标 idx 必须是一个结构体数组,包含 type
和 subs 字段。type 的有效值为 "()"、
"{}" 和 "."。subs 字段可以是
":" 或索引值的元胞数组。
以下示例展示了如何提取矩阵的前两列:
val = magic (3)
⇒ val = [ 8 1 6
3 5 7
4 9 2 ]
idx.type = "()";
idx.subs = {":", 1:2};
subsref (val, idx)
⇒ [ 8 1
3 5
4 9 ]
请注意,这与 val(:, 1:2) 的写法相同。
如果 idx 是一个包含 type 和 subs 字段的空结构体数组,则返回 val。
关键字 end 不能在 subsref 中用于索引赋值。
例如,该类使用的约定是:使用 "()" 进行索引时对多项式求值,而使用 "{}" 进行索引时返回
第 n 个系数(对应第 n 次幂)。subsref 方法的代码如下所示:
function r = subsref (p, s)
if (isempty (s))
error ("@polynomial/subsref: missing index");
endif
switch (s(1).type)
case "()"
idx = s(1).subs;
if (numel (idx) != 1)
error ("@polynomial/subsref: need exactly one index");
endif
r = polyval (fliplr (p.poly), idx{1});
case "{}"
idx = s(1).subs;
if (numel (idx) != 1)
error ("@polynomial/subsref: need exactly one index");
endif
if (isnumeric (idx{1}))
r = p.poly(idx{1}+1);
else
r = p.poly(idx{1});
endif
case "."
fld = s.subs;
if (! strcmp (fld, "poly"))
error ('@polynomial/subsref: invalid property "%s"', fld);
endif
r = p.poly;
otherwise
error ("@polynomial/subsref: invalid subscript type");
endswitch
if (numel (s) > 1)
r = subsref (r, s(2:end));
endif
endfunction
下标赋值的等效功能使用 subsasgn 方法。
newval = subsasgn (val, idx, rhs) ¶根据 idx 指定的下标执行下标赋值操作。
下标 idx 必须是一个结构体数组,包含 type
和 subs 字段。type 的有效值为 "()"、
"{}" 和 "."。subs 字段可以是
":" 或索引值的元胞数组。
以下示例展示了如何将 3x3 矩阵的前两列设为零。
val = magic (3);
idx.type = "()";
idx.subs = {":", 1:2};
val = subsasgn (val, idx, 0)
⇒ [ 0 0 6
0 0 7
0 0 2 ]
请注意,这与 val(:, 1:2) = 0 的写法相同。
如果 idx 是一个包含 type 和 subs 字段的空结构体数组,则返回 rhs。
关键字 end 不能在 subsasgn 中用于索引赋值。
val = optimize_subsasgn_calls () ¶old_val = optimize_subsasgn_calls (new_val) ¶old_val = optimize_subsasgn_calls (new_val, "local") ¶查询或设置 subsasgn 方法调用优化的内部标志。
如果为 true,Octave 将尝试消除调用用户定义类的 subsasgn 方法时的冗余复制。
当在函数内部使用 "local" 选项调用时,该变量将在该函数及其调用的任何子例程中局部更改。
退出函数时恢复原始变量值。
另请参阅: subsasgn。
请注意,subsref 和 subsasgn 方法始终接收完整的索引链,
但它们通常只处理第一个元素。这些方法有责任处理索引链的其余部分(如果需要),
通常是通过再次将其转发给 subsref 或 subsasgn 来实现。
n = numArgumentsFromSubscript (obj, idx, unused) ¶为重载的 subsref 方法覆盖 nargout。
obj 是调用其重载 subsref 方法的对象。
idx 是一个结构体数组,包含 type 和 subs 字段。 有关该结构的描述,请参见 subsref。
第三个输入参数 unused 当前未被使用。它始终是空矩阵 []。
该函数必须返回一个标量整数,该整数将作为 nargout
传递给重载的 subsref 方法。
如果希望在对象的下标表达式中使用 end 关键字,
则必须定义一个 end 方法。例如,多项式类的 end 方法可能如下所示:
function r = end (obj, index_pos, num_indices)
if (num_indices != 1)
error ("polynomial object may only have one index");
endif
r = length (obj.poly) - 1;
endfunction
这是一个相当通用的 end 方法,其行为类似于
Octave 数组类的 end 关键字。以下是使用多项式类的示例:
p = polynomial ([1,2,3,4]);
p{end-1}
⇒ 3
对象本身也可以用作下标表达式中的索引,
这由 subsindex 函数控制。
idx = subsindex (obj) ¶将对象转换为索引向量。
当 obj 是使用类构造函数定义的类对象时,
subsindex 是允许将该类对象转换为有效索引向量的重载方法。
需要特别注意的是,subsindex 必须返回类型为 "double" 的从零开始的实整数向量。
例如,如果类构造函数为:
function obj = myclass (a)
obj = class (struct ("a", a), "myclass");
endfunction
那么 subsindex 函数
function idx = subsindex (obj) idx = double (obj.a) - 1.0; endfunction
可以如下使用:
a = myclass (1:4); b = 1:10; b(a) ⇒ 1 2 3 4
最后,通过提供 colon 方法,对象可以像范围一样使用。
版权所有 © 2024-2026 Octave中文网
ICP备案/许可证号:黑ICP备2024030411号-4