Параллельный Оператор присваивания в Ruby

Я проходил пример от Программирования в книге 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, и чувствует себя действительно странным видеть этот тип присвоения.

Еще один вопрос: действительно ли параллельное присвоение является оператором?

18
задан the Tin Man 14 November 2012 в 14:56
поделиться

1 ответ

Проблема с выполнением присваивания в 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 [] и загромождайте код приведениями. См. этот другой вопрос , на который я недавно ответил, в качестве более практического примера.

33
ответ дан 30 November 2019 в 07:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: