【发布时间】:2012-02-01 13:53:51
【问题描述】:
在 Mathworks File Exchange 存储库中有一些散列或字典类的实现。我所看到的所有内容都使用括号重载来进行键引用,例如
d = Dict;
d('foo') = 'bar';
y = d('foo');
这似乎是一个合理的界面。但是,如果您想轻松拥有包含其他词典的词典,则最好使用大括号 {} 而不是括号,因为这可以让您绕过 MATLAB(似乎是任意的)语法限制,即多个括号不是允许,但允许多个大括号,即
t{1}{2}{3} % is legal MATLAB
t(1)(2)(3) % is not legal MATLAB
因此,如果您希望能够轻松地将字典嵌套在字典中,
dict{'key1'}{'key2'}{'key3'}
as 是 Perl 中的一个常见习语,并且在包括 Python 在内的其他语言中可能并且经常有用,那么除非您想使用 n-1 中间变量来提取字典条目 n 深层,这似乎是一个不错的选择。重写类的 subsref 和 subsasgn 操作以对 {} 执行与以前对 () 相同的操作似乎很容易,并且一切都应该正常工作。
除非我尝试它时没有。
这是我的代码。 (我已经将其简化为最小的情况。这里没有实现实际的字典,每个对象都有一个键和一个值,但这足以说明问题。)
classdef TestBraces < handle
properties
% not a full hash table implementation, obviously
key
value
end
methods(Access = public)
function val = subsref(obj, ref)
% Re-implement dot referencing for methods.
if strcmp(ref(1).type, '.')
% User trying to access a method
% Methods access
if ismember(ref(1).subs, methods(obj))
if length(ref) > 1
% Call with args
val = obj.(ref(1).subs)(ref(2).subs{:});
else
% No args
val = obj.(ref.subs);
end
return;
end
% User trying to access something else.
error(['Reference to non-existant property or method ''' ref.subs '''']);
end
switch ref.type
case '()'
error('() indexing not supported.');
case '{}'
theKey = ref.subs{1};
if isequal(obj.key, theKey)
val = obj.value;
else
error('key %s not found', theKey);
end
otherwise
error('Should never happen')
end
end
function obj = subsasgn(obj, ref, value)
%Dict/SUBSASGN Subscript assignment for Dict objects.
%
% See also: Dict
%
if ~strcmp(ref.type,'{}')
error('() and dot indexing for assignment not supported.');
end
% Vectorized calls not supported
if length(ref.subs) > 1
error('Dict only supports storing key/value pairs one at a time.');
end
theKey = ref.subs{1};
obj.key = theKey;
obj.value = value;
end % subsasgn
end
end
使用此代码,我可以按预期分配:
t = TestBraces;
t{'foo'} = 'bar'
(很明显,t 的默认显示输出中的分配工作。)所以subsasgn 似乎工作正常。
但我无法检索值(subsref 不起作用):
t{'foo'}
??? Error using ==> subsref
Too many output arguments.
错误消息对我来说毫无意义,而且我的 subsref 处理程序的第一个可执行行处的断点从未被命中,所以至少从表面上看,这看起来像是一个 MATLAB 问题,而不是我的代码中的错误。
显然() 括号下标的字符串参数是允许的,因为如果您将代码更改为使用() 而不是{},这将正常工作。 (除非你不能嵌套下标操作,这是练习的对象。)
无论是深入了解我在代码中做错了什么,任何使我正在做的事情不可行的限制,或者嵌套字典的替代实现,都将不胜感激。
【问题讨论】:
标签: oop matlab dictionary operator-overloading hashtable