34.3.1 Определение индексации и индексированного присваивания
К объектам можно обращаться по индексам с помощью круглых или фигурных скобок, например obj(idx) или obj{idx}, а также obj(idx).field. Однако именно программист решает, что означает такая индексация. В случае класса многочленов p(n) может означать коэффициент при n-й степени многочлена или значение многочлена при n. Смысл такого обращения по индексу определяется методом subsref.
-
:
newval =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.
Ключевое слово
endнельзя использовать внутриsubsrefдля индексированных присваиваний.
Например, в этом классе принято, что индексация с помощью "()" вычисляет значение многочлена, а индексация с помощью "{}" возвращает 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’ может содержать":"или массив ячеек со значениями индексов.В следующем примере показано, как присвоить нули двум первым столбцам матрицы размером 3 на 3.
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.
Ключевое слово
endнельзя использовать внутриsubsasgnдля индексированных присваиваний.См. также: 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.
-
:
r =colon(base, limit) -
:
r =colon(base, increment, limit) -
Возвращает результат выражения с двоеточием, соответствующего base, limit и, при наличии, increment.
Эта функция эквивалентна синтаксису оператора
base : limitилиbase : increment : limit.См. также: linspace.
© 1996–2026 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/v9.4.0/Defining-Indexing-And-Indexed-Assignment.html