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