34.3.1 Определение индексации и индексированного присваивания
Объекты могут быть индексированы с помощью скобок или фигурных скобок, как obj(idx) или как obj{idx}, или даже как obj(idx).field. Однако программисту необходимо определить, что фактически означает эта индексация. В случае класса полиномов p(n) может означать либо коэффициент n-ой степени полинома, либо вычисление полинома в точке n. Значение этого индексированного обращения определяется методом subsref.
- : newval = subsref (val, idx) ¶
-
Выполнить операцию выбора элемента с индексом, заданным idx, для val.
Индекс 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.
- : newval = subsasgn (val, idx, rhs) ¶
-
Выполнить операцию индексированного присваивания в соответствии с индексом, заданным idx.
Индекс idx должен быть массивом структуры с полями ‘type’ и ‘subs’. Допустимые значения для ‘type’ —
"()","{}", и".". Поле ‘subs’ может быть либо":"или массивом ячеек значений индексов.Следующий пример показывает, как установить первые два столбца 3x3 матрицы в ноль.
val = magic (3); idx.type = "()"; idx.subs = {":", 1:2}; val = 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) ¶
- : old_val = optimize_subsasgn_calls (new_val, "local") ¶
-
Запрос или установка внутреннего флага для оптимизации вызовов метода
subsasgn.Если true, 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.
© 1996–2023 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/v8.1.0/Defining-Indexing-And-Indexed-Assignment.html