Другая форма присваивания, известная как присваивание кортежу, позволяет выполнять присваивание значений нескольким переменным одновременно.
Прежде чем любая из переменных в левой части получит новое значение, вычисляются все выражения из правой части. Это делает эту разновидность присваивания наиболее полезной, когда некоторые переменные встречаются с обеих сторон оператора присваивания, например, при обмене значений двух переменных:
x, y, = y, x
a[i], a[j] = a[j], a[i]
Или при вычислении наибольшего общего делителя двух целых чисел:
func gcd(x, y, int) int {
for y != 0 {
x, y, = y, x%y
}
return x
}
Или при итеративном вычислении n-1-го числа Фибоначчи:
func fib(n int) int {
x, y, := 0, 1
for i := 0; i < n; i++ {
x, y = y, x+y
}
return x
}
Присваивание кортежу может также сделать последовательность присваиваний более компактной:
i, j, k = 2, 3, 5
При этом (в качестве вопроса стиля) следует избегать присваивания кортежам при наличии сложных выражений: последовательность отдельных инструкций читается легче.
Некоторые выражения, например, как вызов функции с несколькими результатами, производят несколько значений. Когда такой вызов используется в инструкции присваивания, в левой части должно быть столько переменных, сколько результатов возвращает функция:
f, err = os.Open("foo.txt") // Вызов функции возвращает два значения
Зачастую функции используют дополнительные результаты для указания произошедшей ошибки, возвращая значение error
, как
в случае с вызовом функции os.Open()
, либо значение типа bool
, обычно с именем ok
.
Если в присваивании, в котором ожидаются два результата, находится поиск по карте, утверждение о типе или получение из канала - создается дополнительный логический результат:
v, ok = m[key] // Поиск по карте
v, ok = x.(T) // Утверждение о типе
v, ok = <- ch // Получение из канала
Как и в случае объявления переменных, мы можем присвоить ненужные значения пустому идентификатору:
_, err = io.Copy(dst, src) // Отбрасываем количество байтов
_, ok, x.(T) // Проверка типа, игнорируем результат
- Присваивание кортежу - это метод, который позволяет присваивать значения нескольким переменным одновременно, делая код более компактным и понятным;
- Все выражения справа вычисляются перед присваиванием значений переменным слева, что позволяет обменивать значения
переменных, например, вычислять наибольший общий делитель или числа Фибоначчи:
-
func fib(n int) int { x, y, := 0, 1 for i := 0; i < n; i++ { x, y = y, x+y } return x }
-
- Присваивание кортежу удобно для обмена значений между переменными, такими как
x, y = y, x
илиa[i], a[j] = a[j], a[i]
; - Для функций с несколькими результатами присваивание кортежу используется для того, чтобы присвоить значения каждому из
результатов, например:
f, err = os.Open("foo.txt")
; - Дополнительные результаты функций часто используются для указания на ошибки, возвращая значение
error
или булево значениеok
; - В присваивании кортежу можно использовать пустой идентификатор
_
, чтобы игнорировать ненужные значения, например:_, err = io.Copy(dst, src)
; - Присваивание кортежу повышает читаемость и понятность кода, но нужно избегать его использования при наличии сложных выражений, так как последовательность отдельных инструкций может быть легче для чтения.