Определяемые пользователем классы имеют то же поведение индексирования, что и встроенные классы. Классы могут настраивать операции индексирования, перегружая функции, которые 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 - A 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.