Пользовательские классы имеют то же поведение индексации, что и встроенные классы. Классы могут настраивать операции индексации путем перегрузки функций 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
)
A области значений индексов (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{:});
The 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.