Mathworks文件交換存儲庫中有一些散列或字典類的實現。我所看到的所有內容都使用括號重載來進行關鍵引用,例如matlab subsref:{}帶字符串參數失敗,爲什麼?
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'}
的是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問題,而不是我的代碼中的錯誤。
顯然字符串參數()
括號標被允許的,因爲如果你改變了代碼()
,而不是{}
工作能正常工作。 (除了你不能嵌套下標操作,這是練習的對象)。
無論是我在我的代碼中做錯了什麼,有什麼限制使我做的事情變得不可行,嵌套字典的實現將不勝感激。
偉大的,那有效。是的,我想知道很長的答案。 – jmhl 2012-01-03 15:39:40
感謝您的長時間答覆。我猜你在第一個答案後就是這樣,這就說明了這一點。太好了,再次感謝。 – jmhl 2012-01-03 16:03:01
由於R2015b應該重載'numArgumentsFromSubscript'函數 - 請參閱http://stackoverflow.com/questions/8713730/matlab-subsref-with-string-argument-fails-why和Mathworks頁面https:// www的答案。 mathworks.com/help/matlab/matlab_oop/overloading-numel-subsref-and-subsasgn.html。 – nekomatic 2016-10-18 11:39:28