Использование _ в лямбда-функциях scala - PullRequest
36 голосов
/ 06 октября 2011

Может кто-нибудь объяснить, почему я могу сделать:

a.mapValues(_.size)

вместо

a.mapValues(x => x.size)

но я не могу сделать

a.groupBy(_)

вместо

a.groupBy(x => x)

Ответы [ 2 ]

41 голосов
/ 06 октября 2011

Когда вы пишете a.groupBy(_), компилятор понимает это как анонимную функцию:

x => a.groupBy(x)

Согласно Scala Specification §6.23, заполнитель подчеркивания в выражении заменяется анонимным параметром. Итак:

  • _ + 1 расширен до x => x + 1
  • f(_) расширен до x => f(x)
  • _ не раскрывается сам по себе (заполнитель не является частью какого-либо выражения).

Выражение x => a.groupBy(x) запутает компилятор, поскольку оно не может вывести тип x. Если a является некоторой коллекцией элементов типа E, то компилятор ожидает, что x будет функцией типа (E) => K, но тип K не может быть выведен ...

16 голосов
/ 06 октября 2011

Это не легко увидеть здесь:

a.groupBy(_)

Но это проще увидеть примерно так:

a.mkString("<", _, ">")

Я частично применяю метод /функция.Я применяю его к некоторым параметрам (к первому и последнему) и оставляю второй параметр неприменимым, поэтому получаю новую функцию, подобную этой:

x => a.mkString("<", x, ">")

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

a.mapValues(_.size)
a.mapValues(x => x.size)

Легко запутаться, потому что оба они приводят к анонимной функции.На самом деле, есть третье подчеркивание, которое используется для преобразования метода в значение метода (которое также является анонимной функцией), например:

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