8.6 Присваивания
Присваивание — это выражение, которое сохраняет новое значение в переменную. Например, следующее выражение присваивает значение 1 переменной z:
z = 1
После выполнения этого выражения переменная z имеет значение 1. Предыдущее значение z, которое имела переменная до присваивания, забывается. Знак ‘=’ называется оператором присваивания.
Присваивания могут также сохранять строковые значения. Например, следующее выражение сохранит значение "this food is good" в переменной message:
thing = "food" predicate = "good" message = [ "this " , thing , " is " , predicate ]
(Это также иллюстрирует конкатенацию строк.)
Большинство операторов (сложение, конкатенация и т. д.) не имеют эффектов, кроме вычисления значения. Если вы игнорируете это значение, вы можете и не использовать этот оператор. Оператор присваивания отличается. Он действительно производит значение, но даже если вы его игнорируете, присваивание всё равно оказывает своё влияние путём изменения переменной. Мы называем это побочным эффектом.
Левый операнд присваивания не обязательно должен быть переменной (см. Переменные). Он также может быть элементом матрицы (см. Индексные выражения) или списком возвращаемых значений (см. Вызов функций). Все эти элементы называются lvalue, что означает, что они могут стоять слева от оператора присваивания. Правый операнд может быть любым выражением. Он производит новое значение, которое присваивание сохраняет в указанной переменной, элементе матрицы или списке возвращаемых значений.
Важно отметить, что переменные не имеют постоянных типов. Тип переменной просто тип того значения, которое она случайно хранит в данный момент. В следующем фрагменте программы переменная foo сначала имеет числовое значение, а затем — строковое:
octave:13> foo = 1 foo = 1 octave:13> foo = "bar" foo = bar
Когда второе присваивание даёт foo строковое значение, тот факт, что ранее оно имело числовое значение, забывается.
Присваивание скаляра индексированной матрице устанавливает все элементы, на которые ссылаются индексы, в скалярное значение. Например, если a — это матрица с как минимум двумя столбцами,
a(:, 2) = 5
устанавливает все элементы во втором столбце a в 5.
Присваивание пустой матрицы ‘[]’ в большинстве случаев позволяет вам удалять строки или столбцы матриц и векторов. См. Пустые матрицы. Например, для матрицы 4x5 A, присваивание
A (3, :) = []
удаляет третью строку из A, а присваивание
A (:, 1:2:5) = []
удаляет первый, третий и пятый столбцы.
Присваивание является выражением, поэтому оно имеет значение. Таким образом, z = 1 как выражение имеет значение 1. Одно следствие этого заключается в том, что вы можете записать несколько присваиваний вместе:
x = y = z = 0
сохраняет значение 0 во всех трёх переменных. Это происходит потому, что значение z = 0, которое равно 0, сохраняется в y, а затем значение y = z = 0, которое равно 0, сохраняется в x.
Это также верно для присваиваний спискам значений, поэтому следующее является допустимым выражением
[a, b, c] = [u, s, v] = svd (a)
что полностью эквивалентно
[u, s, v] = svd (a) a = u b = s c = v
В выражениях такого рода количество значений в каждой части выражения необязательно должно совпадать. Например, выражение
[a, b] = [u, s, v] = svd (a)
эквивалентно
[u, s, v] = svd (a) a = u b = s
Однако количество значений слева от выражения не может превышать количество значений справа. Например, следующее вызовет ошибку.
[a, b, c, d] = [u, s, v] = svd (a); -| error: element number 4 undefined in return list
Символ ~ может использоваться в качестве заполнителя в списке lvalue, указывая, что соответствующее возвращаемое значение должно быть проигнорировано и не сохранено нигде:
[~, s, v] = svd (a);
Это более чисто и эффективнее с точки зрения памяти, чем использование фиктивной переменной. Значение nargout для выражения правой части не затрагивается. Если присваивание используется как выражение, то возвращаемое значение — это список значений, разделенных запятыми, с пропущенными проигнорированными значениями.
Очень распространённый шаблон программирования — это увеличение существующей переменной на заданное значение, например так
a = a + 2;
Это можно записать более ясно и компактно, используя оператор +=
a += 2;
Аналогичные операторы также существуют для вычитания (-=), умножения (*=) и деления (/=). Выражение вида
expr1 op= expr2
вычисляется как
expr1 = (expr1) op (expr2)
где op может быть либо +, либо -, либо *, либо /, при условии, что expr2 — это простое выражение без побочных эффектов. Если expr2 также содержит оператор присваивания, то это выражение вычисляется как
temp = expr2 expr1 = (expr1) op temp
где temp — это временное значение-заполнитель, хранящее вычисленное значение expr2. Таким образом, выражение
a *= b+1
вычисляется как
a = a * (b+1)
и не
a = a * b + 1
Вы можете использовать присваивание везде, где требуется выражение. Например, допустимо написать x != (y = 1), чтобы установить y в 1, а затем проверить, равно ли x 1. Но такой стиль делает программы сложными для чтения. За исключением одноразовой программы, следует переписать его, чтобы избавиться от таких вложенных присваиваний. Это никогда не бывает очень сложно.
© 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/Assignment-Ops.html