Я определяю функцию f как:
def f(x: Int): Int = x % 2
Это не функция, это метод. Они принципиально отличаются:
- Методы могут быть универсальными, а функции — нет.
- Методы могут иметь необязательные параметры с аргументами по умолчанию, а функции — нет.
- Методы могут иметь varargs, а функции — нет.
- Методы могут иметь неявные аргументы, а функции — нет.
Это 4 ограничения, которые функции имеют по сравнению с методами. Теперь, если они так ограничены, почему мы их используем? Что ж, у функций есть одно важное преимущество:
- Функции — это объекты, а методы — нет (они принадлежат объектам).
Это означает: функции можно назначать val
s/var
s, их можно передавать в качестве аргументов функциям, методам и конструкторам, их можно возвращать из функций и методов. Методы ничего из этого сделать не могут: Scala — это объектно-ориентированный язык, все объекты, которыми может манипулировать программа, являются объектами, а методы — нет.
Итак, почему
rdd.groupBy(f)
Работа?
Ну, вы можете преобразовать метод в частично примененную функцию (здесь «частично примененный» означает «частично примененный к this
», а не к подмножеству аргументов) через -расширение:
val fn = f _
// => fn: Int => Int = <function1>
Здесь, как это часто бывает в Scala, символ подчеркивания используется в качестве заполнителя (в данном случае для еще не предоставленных аргументов). Мы исправили this
метода, оставили аргументы открытыми и создали функцию, соответствующую этому методу.
В некоторых случаях Scala будет знать, что вы хотите выполнить -расширение, даже без явного предоставления символа подчеркивания. Вот почему
rdd.groupBy(f)
работает. Это называется неявное расширение (§6.26.2, случай 3 Спецификации языка Scala) и из-за неоднозначности работает только в ограниченном количестве случаев.
Однако, объяснив все это, я должен признать, что не понимаю, почему ваш второй пример не работает. Согласно моему прочтению спецификации, так и должно быть.
IOW: фундаментальная проблема, с которой вы столкнулись, заключается в том, что вы путаете функции и методы, но в этом конкретном случае это действительно должно работать (по крайней мере, в соответствии с моей интерпретацией спецификации, хотя явно не в соответствии с интерпретацией авторов компилятора).
person
Jörg W Mittag
schedule
19.07.2014
def
) и функциями в Scala. Взгляните на этот ответ, чтобы увидеть, как они взаимодействуют: stackoverflow.com/a/2394063/58808 - person Ionuț G. Stan   schedule 18.07.2014rdd.groupBy(f _, 10)
- person samthebest   schedule 21.07.2014