我在 Matlab 中有一个简单的类:
classdef DummyClass
properties
name = '';
value = nan;
end
methods
function obj = DummyClass(varargin)
if nargin > 0
obj.name = varargin{1};
if nargin > 1
obj.value = varargin{2};
end
end
end
end
end
我定义了一个 DummyClass 对象数组,然后调用 name 属性:
t1(1) = DummyClass("a1", 1);
t1(2) = DummyClass("a2", 2);
t1.name
结果是:
ans =
"a1"
ans =
"a2"
我的最终目标是能够使用“name”属性作为对象的输入参数来访问“value”属性。例如,
t1("a1")
应返回 1。
作为第一步,我在 DummyClass 中添加 subsref 方法:
classdef DummyClass
properties
name = '';
value = nan;
end
methods
function obj = DummyClass(varargin)
if nargin > 0
obj.name = varargin{1};
if nargin > 1
obj.value = varargin{2};
end
end
end
function out = subsref(obj, S)
out = 1;
end
end
end
当我现在尝试使用 t1.name 访问 name 属性时,它会给出错误(请注意,它没有提及发生错误的行)
” 使用索引时出错 输出参数太多。”
显然 subsref 不能处理对象数组。我该如何修改它才能使后者成为可能?
我尝试使用 subsasgn 代替,但也没有成功(请参阅 stackoverflow 中的类似问题)
知道你想要做什么,我建议保留你的基类不变,并在容器类中处理你想要的功能。
使用尽可能简单的基本示例类:
classdef DummyClass
properties
name = '';
value = nan;
end
methods
function obj = DummyClass(varargin)
if nargin > 0
obj.name = varargin{1};
if nargin > 1
obj.value = varargin{2};
end
end
end
end
end
您可以构造一个容器类,它将保存这些数组,并根据您感兴趣的情况调整
subsref()
函数:
classdef DummyClassArray < handle
properties
dummies (:,1) DummyClass
end
methods
function obj = DummyClassArray()
end
function obj = AddDummy(obj,dc)
obj.dummies(end+1,1) = dc ;
end
function varargout = subsref(obj,s)
% [varargout{1:nargout}] = builtin('subsref',obj,s) ;
switch s(1).type
case '.'
[varargout{1:nargout}] = builtin('subsref',obj,s);
case '()'
if length(s) == 1
% if the parameter is an numeric index => return value at specified index
% if the parameter is a string => return value at matching name
p = s.subs{1} ;
if isnumeric(p)
[varargout{1:nargout}] = find_dummy_by_index(obj, p) ;
elseif ischar(p) || isstring(p)
[varargout{1:nargout}] = find_dummy_by_name(obj,p) ;
end
else
% Use built-in for any other expression
[varargout{1:nargout}] = builtin('subsref',obj,s);
end
case '{}'
[varargout{1:nargout}] = builtin('subsref',obj,s);
otherwise
error('Not a valid indexing expression')
end
end
function out = find_dummy_by_name(obj, name2find)
n = numel(obj.dummies);
out = [] ;
for k=1:n
if strcmpi(obj.dummies(k).name, name2find)
out = obj.dummies(k).value ;
break
end
end
end
function out = find_dummy_by_index(obj, idx2find)
% This is just to make sure the provided index is not out of
% bound
n = numel(obj.dummies);
if idx2find <= n
out = obj.dummies(idx2find).value ;
else
out = [] ; % Probably wise to throw an error here
end
end
end
end
有了它,您现在可以通过指定关联的
value
来访问任何 name
属性:
% build the base example objects
t1(1) = DummyClass("a1", 10);
t1(2) = DummyClass("a2", 20);
% instanciate and populate the container array
dca = DummyClassArray ;
dca.AddDummy(t1(1)) ;
dca.AddDummy(t1(2))
ans =
DummyClassArray with properties:
dummies: [2×1 DummyClass]
现在:
>> dca("a1")
ans =
10
>> dca(2)
ans =
20
>> dca.dummies
ans =
2×1 DummyClass array with properties:
name
value
现在类容器实际上已经是准系统来说明功能了。为了增加使用类容器的稳健性和舒适性,您应该:
subassign
,这样您也可以修改一个值(通过使用其名称进行索引)。例如:dca("a1")=42;