Как работает (1..4) .inject (&: +) в Ruby - PullRequest
12 голосов
/ 15 февраля 2011

Я нахожу этот код в Ruby довольно интригующим

(1..4).inject(&:+)

Хорошо, я знаю, что делает inject, и знаю, что этот код в основном эквивалентен

(1..4).inject(0) {|a,n| a + n}

но как именно это работает?

Почему &:+ - это то же самое, что и запись блока {|a,n| a + n}?

Почему ему не нужно начальное значение?Я в порядке с начальным значением, равным 0, но (1..4).inject(&:*) также работает, и там начальное значение должно быть 1 ...

1 Ответ

14 голосов
/ 15 февраля 2011

С Рубиновая документация :

Если вместо этого указать символ, то каждый элемент в коллекции будет передан в именованный метод memo

Таким образом, указание символа эквивалентно передаче следующего блока: {|memo, a| memo.send(sym, a)}

Если вы явно не укажете начальное значение для памятки, то в качестве начального значения памятки будет использоваться первый элемент коллекции.

Итак, магии нет, Ruby просто берет первый элемент в качестве начального значения и начинает вводить из второго элемента. Вы можете проверить это, написав [].inject(:+): он возвращает nil, а не [].inject(0, :+), который возвращает 0.

Редактировать: я не заметил амперсанд. Вам это не нужно, inject будет работать с символом. Но если вы напишите это, символ преобразуется в блок, это может быть полезно с другими методами

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...