34.3.1 Определение индексирования и индексированного присваивания
Объекты могут быть индексированы с помощью скобок или фигурных скобок, как obj(idx) или obj{idx}, или даже как obj(idx).field. Однако программист должен определить, что это индексирование фактически означает. В случае класса многочленов p(n) может означать либо коэффициент n-ой степени многочлена, либо вычисление многочлена в точке n. Значение этого индексирования определяется методом subsref.
- subsref (val, idx)
-
Выполняет операцию выбора элемента по индексу на val в соответствии с индексом, заданным idx.
Индекс idx должен быть массивом структур с полями «type» и «subs». Допустимые значения для «type» являются
"()","{}", и".". Поле «subs» может быть либо":", либо массивом ячеек индексных значений.Следующий пример демонстрирует, как извлечь первые два столбца матрицы
val = magic (3) ⇒ val = [ 8 1 6 3 5 7 4 9 2 ] idx.type = "()"; idx.subs = {":", 1:2}; subsref (val, idx) ⇒ [ 8 1 3 5 4 9 ]Обратите внимание, что это то же самое, что и написание
val(:, 1:2).Если idx — пустой массив структуры с полями «type» и «subs», вернуть val.
Например, этот класс использует соглашение, что индексирование с "()" вычисляет многочлен, а индексирование с "{}" возвращает n-ый коэффициент (степени n). Код метода subsref выглядит так
function r = subsref (p, s)
if (isempty (s))
error ("@polynomial/subsref: missing index");
endif
switch (s(1).type)
case "()"
idx = s(1).subs;
if (numel (idx) != 1)
error ("@polynomial/subsref: need exactly one index");
endif
r = polyval (fliplr (p.poly), idx{1});
case "{}"
idx = s(1).subs;
if (numel (idx) != 1)
error ("@polynomial/subsref: need exactly one index");
endif
if (isnumeric (idx{1}))
r = p.poly(idx{1}+1);
else
r = p.poly(idx{1});
endif
case "."
fld = s.subs;
if (! strcmp (fld, "poly"))
error ('@polynomial/subsref: invalid property "%s"', fld);
endif
r = p.poly;
otherwise
error ("@polynomial/subsref: invalid subscript type");
endswitch
if (numel (s) > 1)
r = subsref (r, s(2:end));
endif
endfunction
Эквивалентная функциональность для индексированных присваиваний использует метод subsasgn.
- subsasgn (val, idx, rhs)
-
Выполняет операцию присваивания по индексу в соответствии с индексом, заданным idx.
Индекс idx должен быть массивом структур с полями «type» и «subs». Допустимые значения для «type» являются
"()","{}", и".". Поле «subs» может быть либо":", либо массивом ячеек индексных значений.Следующий пример показывает, как установить первые два столбца 3x3 матрицы в ноль.
val = magic (3); idx.type = "()"; idx.subs = {":", 1:2}; subsasgn (val, idx, 0) ⇒ [ 0 0 6 0 0 7 0 0 2 ]Обратите внимание, что это то же самое, что и запись
val(:, 1:2) = 0.Если idx — пустой массив структуры с полями «type» и «subs», вернуть rhs.
См. также: subsref, substruct, optimize_subsasgn_calls.
- val = optimize_subsasgn_calls ()
- old_val = optimize_subsasgn_calls (new_val)
- optimize_subsasgn_calls (new_val, "local")
-
Запрос или установка внутреннего флага для оптимизации вызовов метода
subsasgn.Если значение истинно, Octave попытается исключить излишнее копирование при вызове метода
subsasgnпользовательского класса.При вызове изнутри функции с опцией
"local", переменная изменяется локально для функции и любых вызываемых подпрограмм. Исходное значение переменной восстанавливается при выходе из функции.См. также: subsasgn.
Обратите внимание, что методы subsref и subsasgn всегда получают всю цепочку индексов, в то время как обычно они обрабатывают только первый элемент. Ответственность этих методов — обработать остальную цепочку (если это необходимо), обычно перенаправив ее снова к subsref или subsasgn.
Если вы хотите использовать ключевое слово end в индексированных выражениях объекта, должен быть определен метод end. Например, метод end для класса многочленов может выглядеть так
function r = end (obj, index_pos, num_indices)
if (num_indices != 1)
error ("polynomial object may only have one index");
endif
r = length (obj.poly) - 1;
endfunction
что является довольно универсальным методом end, который имеет поведение, аналогичное ключевому слову end для классов массивов Octave. Пример использования с классом многочленов тогда
p = polynomial ([1,2,3,4]);
p{end-1}
⇒ 3
Объекты также могут использоваться как индексы в индексированных выражениях, и это регулируется функцией subsindex.
- idx = subsindex (obj)
-
Преобразует объект в вектор индексов.
Когда obj является объектом класса, определенным с конструктором класса, тогда
subsindexявляется перегруженным методом, который позволяет преобразовать этот объект класса в допустимый индексный вектор. Важно отметить, чтоsubsindexдолжен возвращать вещественный целочисленный вектор с нулевым началом, класса"double". Например, если конструктор класса былfunction obj = myclass (a) obj = class (struct ("a", a), "myclass"); endfunctionтогда функция
subsindexfunction idx = subsindex (obj) idx = double (obj.a) - 1.0; endfunction
могла использоваться следующим образом
a = myclass (1:4); b = 1:10; b(a) ⇒ 1 2 3 4
Наконец, объекты могут использоваться как диапазоны, предоставив метод colon.
- r = colon (base, limit)
- r = colon (base, increment, limit)
-
Возвращает результат выражения двоеточия, соответствующего base, limit, и необязательно increment.
Эта функция эквивалентна синтаксису оператора
base : limitилиbase : increment : limit.См. также: linspace.
© 1996–2022 The Octave Project Developers
Permission is granted to make and distribute verbatim copies of this manual provided the copyright notice and this permission notice are preserved on all copies.
Permission is granted to copy and distribute modified versions of this manual under the conditions for verbatim copying, provided that the entire resulting derived work is distributed under the terms of a permission notice identical to this one.Permission is granted to copy and distribute translations of this manual into another language, under the above conditions for modified versions.
https://docs.octave.org/v5.2.0/Defining-Indexing-And-Indexed-Assignment.html