Может кто-нибудь объяснить мне, почему я могу сделать:
a.mapValues(_.size)
вместо
a.mapValues(x => x.size)
но я не могу сделать
a.groupBy(_)
вместо
a.groupBy(x => x)
Может кто-нибудь объяснить мне, почему я могу сделать:
a.mapValues(_.size)
вместо
a.mapValues(x => x.size)
но я не могу сделать
a.groupBy(_)
вместо
a.groupBy(x => x)
Это не легко увидеть здесь:
a.groupBy(_)
Но легче видеть это примерно так:
a.mkString("<", _, ">")
Я частично применяю метод/функцию. Я применяю его к некоторым параметрам (первый и последний) и оставляя второй параметр непримененным, поэтому я получаю новую функцию следующим образом:
x => a.mkString("<", x, ">")
Первый пример - это особый случай, когда частично применяется единственный параметр. Однако, когда вы используете подчеркивание в выражении, это означает позиционные параметры в анонимной функции.
a.mapValues(_.size)
a.mapValues(x => x.size)
Легко запутаться, потому что они оба приводят к анонимной функции. На самом деле есть третий знак подчеркивания, который используется для преобразования метода в значение метода (которое также является анонимной функцией), например:
a.groupBy _
Когда вы пишете a.groupBy(_)
, компилятор понимает его как анонимную функцию:
x => a.groupBy(x)
Согласно Scala Спецификации §6.23, замещающий знак подчеркивания в выражении заменяется анонимным параметром. Итак:
_ + 1
расширяется до x => x + 1
f(_)
расширяется до x => f(x)
_
не размножается сам по себе (заполнитель не является частью какого-либо выражения).Выражение x => a.groupBy(x)
будет путать компилятор, потому что он не может вывести тип x
. Если a
- некоторая коллекция элементов типа E
, то компилятор ожидает, что x
будет функцией типа (E) => K
, но тип K
не может быть выведен...