Для R2021b и позже, рекомендуемый процесс для настройки индексации должен использовать модульные суперклассы индексации вместо того, чтобы перегрузить subsref
и subsasgn
. Для получения дополнительной информации смотрите, Настраивают Индексирование объектов.
Пользовательские классы имеют те же поведения индексации как тот из встроенных классов. Классы могут настроить операции индексации путем перегрузки функций что MATLAB® вызовы, чтобы выполнить выражения индексации. Перегрузитесь subsref
и subsasgn
функции, когда это необходимо, чтобы задать специальные поведения для индексируемой ссылки и присвоения.
MATLAB вызывает subsref
и subsasgn
методы вашего класса с этими аргументами.
Метод | Входной параметр | Вывод |
---|---|---|
|
|
|
|
|
|
Если ваш проект класса требует, чтобы индексирующие операции возвратили или присвоили различный номер значений, чем номер, заданный операцией индексации значения по умолчанию, перегрузились numArgumentsFromSubscript
функционируйте, чтобы управлять nargout
для subsref
и nargin
для subsasgn
. Для получения дополнительной информации и примеры, смотрите numArgumentsFromSubscript
.
Структура индексации содержит информацию, которая описывает выражение индексации. Методы класса используют информацию в структуре индексации, чтобы выполнить выражение и реализовать пользовательское поведение.
Например, CustomIndex
класс задает свойство, которое можно использовать в индексации выражений.
classdef CustomIndex properties DataArray end end
Создайте объект и присвойте матрицу 5 на 5, созданную magic
функционируйте к DataArray
свойство.
a = CustomIndex; a.DataArray = magic(5);
Это преобразованное в нижний индекс ссылочное выражение возвращает первую строку матрицы 5 на 5.
a.DataArray(1,:)
ans = 17 24 1 8 15
Это выражение присваивает новые значения первой строке массива, сохраненного в DataArray
свойство.
a.DataArray(1,:) = [1 2 3 4 5];
Этот оператор присваивания использование:
A
введите ссылку
Имя свойства после точки (то есть, DataArray
)
Область значений индексов (1,:
) в круглых скобках
Структура индексации содержит эту информацию в type
и subs
поля .
При выполнении выражения индексации MATLAB вызывает класс subsref
или subsasgn
метод, если класс перегружает эти функции. Один из аргументов, переданных методу, является структурой индексации. Структура индексации имеет два поля:
type
— Один из трех возможных типов индексации: '.'
, '()'
, '{}'
subs
— char
вектор с именем свойства или массивом ячеек индексов, используемых в выражении, включая :
и end
.
Если выражение индексации является составным выражением, то MATLAB передает массив структур, один struct
для каждого уровня индексации. Например, в этом выражении:
a.DataArray(1,:)
массив структур индексации S
имеет эти значения:
S(1).type
установлен в '.'
, указание, что первая операция индексации является точкой.
s(1).subs
установлен в имя свойства, 'DataArray'
Второй уровень индексации в своей стихии структуры индексации:
S(2).types
установлен в '()'
указание на вторую операцию индексации является индексацией круглых скобок
S(2).subs
установлен в массив ячеек, содержащий индексы {[1],[:]}
Перегружаться subsref
и subasgn
функции:
Определите полное выражение индексации с помощью types
и subs
поля структуры индексации.
Реализуйте специализированные поведения для операций индексации, поддержанных классом.
Возвратите соответствующие значения или измененные объекты в ответ на вызов MATLAB.
A switch
оператор является удобным способом обнаружить первый уровень индексации. Существует три типа индексации — точка, круглые скобки и фигурные скобки. Каждый case
блокируйтесь в switch
оператор реализует все выражения индексации, которые начинаются с того типа первого уровня индексации.
Методы должны реализовать все выражения индексации, которые поддерживает класс. Если вы не настраиваете конкретный тип индексации, вызовите встроенную функцию, чтобы обработать то выражение.
Используйте длину массива структур индексации, и индексация типа задают условные операторы для составных выражений индексации.
subsref
МетодСледующая среда для subsref
метод показывает, как использовать информацию в структуре индексации в условных операторах. Ваше приложение может включить другие выражения, не показанные здесь.
function varargout = subsref(obj,s) switch s(1).type case '.' if length(s) == 1 % Implement obj.PropertyName ... elseif length(s) == 2 && strcmp(s(2).type,'()') % Implement obj.PropertyName(indices) ... else [varargout{1:nargout}] = builtin('subsref',obj,s); end case '()' if length(s) == 1 % Implement obj(indices) ... elseif length(s) == 2 && strcmp(s(2).type,'.') % Implement obj(ind).PropertyName ... elseif length(s) == 3 && strcmp(s(2).type,'.') && strcmp(s(3).type,'()') % Implement obj(indices).PropertyName(indices) ... else % Use built-in for any other expression [varargout{1:nargout}] = builtin('subsref',obj,s); end case '{}' if length(s) == 1 % Implement obj{indices} ... elseif length(s) == 2 && strcmp(s(2).type,'.') % Implement obj{indices}.PropertyName ... else % Use built-in for any other expression [varargout{1:nargout}] = builtin('subsref',obj,s); end otherwise error('Not a valid indexing expression') end
Используя varargout
поскольку возвращенное значение позволяет методу работать с массивами объектов. Например, предположите, что вы хотите поддержать возврат списка, разделенного запятыми с выражением как этот:
[x1,...xn] = objArray.PropertyName(Indices)
Это выражение приводит к двухэлементному массиву структур индексации. Тип первого уровня является точкой ('.'
) и второй уровень является круглыми скобками ('()'
). Создайте varargout
массив ячеек с каждым значением в массиве.
case '.' ... if length(s)==2 && strcmp(s(2).type,'()') prop = s(1).subs; % Property name n = numel(obj); % Number of elements in array varargout = cell(1,n); % Preallocate cell array for k = 1:n varargout{k} = obj(k).(prop).(s(2).subs); end end ... end
Следующая среда для subsasgn
метод показывает, как использовать структуру индексации в условных операторах то присвоение реализации операции.
function obj = subsasgn(obj,s,varargin) % Allow subscripted assignment to uninitialized variable if isequal(obj,[]) % obj = ClassName.empty; end switch s(1).type case '.' if length(s) == 1 % Implement obj.PropertyName = varargin{:}; ... elseif length(s) == 2 && strcmp(s(2).type,'()') % Implement obj.PropertyName(indices) = varargin{:}; ... else % Call built-in for any other case obj = builtin('subsasgn',obj,s,varargin{:}); end case '()' if length(s) == 1 % Implement obj(indices) = varargin{:}; elseif length(s) == 2 && strcmp(s(2).type,'.') % Implement obj(indices).PropertyName = varargin{:}; ... elseif length(s) == 3 && strcmp(s(2).type,'.') && strcmp(s(3).type,'()') % Implement obj(indices).PropertyName(indices) = varargin{:}; ... else % Use built-in for any other expression obj = builtin('subsasgn',obj,s,varargin{:}); end case '{}' if length(s) == 1 % Implement obj{indices} = varargin{:} ... elseif length(s) == 2 && strcmp(s(2).type,'.') % Implement obj{indices}.PropertyName = varargin{:} ... % Use built-in for any other expression obj = builtin('subsasgn',obj,s,varargin{:}); end otherwise error('Not a valid indexing expression') end end
Используя varargin
поскольку значение правой стороны оператора присваивания позволяет методу работать с массивами объектов. Например, предположите, что вы хотите поддержать присвоение списка, разделенного запятыми с выражением как этот:
C = {'one';'two';'three'}; [objArray.PropertyName] = C{:}
Это выражение приводит к структуре индексации с точечным типом ('.'
) индексация массива ячеек C
на правой стороне оператора присваивания производит список, разделенный запятыми. Этот код присваивает один элемент списка каждому свойству в объектном массиве.
case '.' if length(s)==1 prop = s(1).subs; % Property name n = numel(obj); % Number of elements in array for k = 1:n obj(k).(prop) = varargin{k}; end end end
Присвоение элементу неинициализированной переменной приводит к вызову subsasgn
метод класса на правой стороне присвоения. Например, этот класс задает subsasgn
метод, который просто вызывает встроенный subsasgn
метод для индексации круглой скобки.
classdef MyClass methods function obj = subsasgn(obj,s,varargin) switch s(1).type case '()' obj = builtin('subsasgn',obj,s,varargin{:}); end end end end
При попытке присвоить объект MyClass
к первому элементу неинициализированной переменной, B(1)
в следующем операторе MATLAB вызывает subsasgn
метод MyClass
с пустым двойным ([]
) в качестве первого аргумента. Присвоение может вызвать ошибку потому что subsasgn
метод должен быть передан объект класса.
clear B
B(1) = MyClass;
The following error occurred converting from MyClass to double: Conversion to double from MyClass is not possible. Error in MyClass/subsasgn (line 6) obj = builtin('subsasgn',obj,s,varargin{:});
subsasgn
метод может обнаружить эту ситуацию и принять соответствующие меры, такие как возврат полезного сообщения об ошибке, если класс не поддерживает этот тип присвоения или преобразование входа к объекту класса и передачи его к subsasgn
.
Например, потому что MyClass
может позволить преобразованное в нижний индекс присвоение на неинициализированную переменную, subsasgn
метод может изменить первый аргумент от пустого дважды к пустому MyClass
объект.
Используйте isequal
функционируйте, чтобы проверять вход и empty
статический метод создать пустой объект.
classdef MyClass methods function obj = subsasgn(obj,s,varargin) if isequal(obj,[]) obj = MyClass.empty; end obj = builtin('subsasgn',obj,s,varargin{:}); end end end
Преобразованное в нижний индекс присвоение на неинициализированную переменную теперь избегает предыдущей ошибки.
clear B
B(1) = MyClass;
B = MyClass with no properties.