Я проходил пример от Программирования в книге Ruby:
def fib_up_to(max)
i1, i2 = 1, 1 # parallel assignment (i1 = 1 and i2 = 1)
while i1 <= max
yield i1
i1, i2 = i2, i1+i2
end
end
fib_up_to(100) {|f| print f, " " }
Это просто печатает Числа Фибоначчи до 100. Это прекрасно. Когда я заменяю параллельное присвоение:
i1 = i2
i2 = i1+i2
Я не получаю желаемый вывод.
Действительно ли желательно использовать параллельные присвоения? Я происхожу из среды Java, и чувствует себя действительно странным видеть этот тип присвоения.
Еще один вопрос: действительно ли параллельное присвоение является оператором?
Проблема с выполнением присваивания в 2 отдельных операторах заключается в том, что i2 = i1 + i2
затем будет использовать новое значение i1
, а не предыдущее значение, необходимое для правильного создания Последовательность Фибоначчи.
Когда вы используете параллельное присваивание, все выражения в правой части сначала оцениваются, а затем присваиваются принимающим переменным в левой части.
Параллельное присваивание не является специальным оператором. По сути, то, что находится справа, действует как массив, где, если мы перечисляем несколько переменных в левой части, массив распаковывается и присваивается соответствующим переменным.
Вот еще несколько примеров:
irb(main):020:0> a = 1, 2 # assign to a single variable
=> [1, 2]
irb(main):021:0> a
=> [1, 2]
irb(main):022:0> a, b = 1, 2 # unpack into separate variables
=> [1, 2]
irb(main):023:0> a
=> 1
irb(main):024:0> b
=> 2
irb(main):025:0> a, b = [1, 2, 3] # 3 is 'lost' as no receiving variable
=> [1, 2, 3]
irb(main):026:0> a
=> 1
irb(main):027:0> b
=> 2
irb(main):028:0> first, *rest = [1, 2, 3] # *rest consumes the remaining elements
=> [1, 2, 3]
irb(main):029:0> first
=> 1
irb(main):030:0> rest
=> [2, 3]
Это полезная функция Ruby, например, она упрощает использование методов, возвращающих несколько значений, например.
def sum_and_difference(a, b)
a + b, a - b
end
sum, difference = sum_and_difference 5, 3
В Java наиболее подходящим вариантом было бы иметь метод, возвращающий int []
, но если бы мы хотели вернуть строку и число, нам нужно было бы создать небольшой POJO, который будет действовать как структура для возвращаемое значение или return Object []
и загромождайте код приведениями. См. этот другой вопрос , на который я недавно ответил, в качестве более практического примера.