scalabook

Форк
0
83 строки · 4.7 Кб

Eta расширение

Если посмотреть на Scaladoc для метода map

в классах коллекций Scala, то можно увидеть, что метод определен для приема функции:

def map[B](f: (A) => B): List[B]
-----------

Действительно, в Scaladoc сказано: "f

— это функция, применяемая к каждому элементу". Но, несмотря на это, каким-то образом в map
можно передать метод, и он все еще работает:

def times10(i: Int) = i * 10
List(1, 2, 3).map(times10)
// res0: List[Int] = List(10, 20, 30)

Как это работает? Как можно передать метод в map

, который ожидает функцию?

Технология, стоящая за этим, известна как Eta Expansion. Она преобразует выражение типа метода в эквивалентное выражение типа функции, и делает это легко и незаметно.

Различия между методами и функциями

Исторически методы были частью определения класса, хотя в Scala 3 методы могут быть вне классов, такие как определения верхнего уровня и методы расширения.

В отличие от методов, функции сами по себе являются полноценными объектами, что делает их объектами первого класса.

Их синтаксис также отличается. В этом примере показано, как задать метод и функцию, которые выполняют одну и ту же задачу, определяя, является ли заданное целое число четным:

def isEvenMethod(i: Int) = i % 2 == 0 // метод
val isEvenFunction = (i: Int) => i % 2 == 0 // функция

Функция действительно является объектом, поэтому ее можно использовать так же, как и любую другую переменную, например, помещая в список:

val functions = List(isEvenFunction)

И наоборот, технически метод не является объектом, поэтому в Scala 2 метод нельзя было поместить в список, по крайней мере, напрямую, как показано в этом примере:

// В этом примере показано сообщение об ошибке в Scala 2
val methods = List(isEvenMethod)
^
error: missing argument list for method isEvenMethod
Unapplied methods are only converted to functions when a function type is expected.
You can make this conversion explicit by writing `isEvenMethod _` or `isEvenMethod(_)` instead of `isEvenMethod`.

Как показано в этом сообщении об ошибке, в Scala 2 существует ручной способ преобразования метода в функцию, но важной частью для Scala 3 является то, что технология Eta Expansion улучшена, поэтому теперь, когда попытаться использовать метод в качестве переменной, он просто работает — не нужно самостоятельно выполнять ручное преобразование:

val functions = List(isEvenFunction)
val methods = List(isEvenMethod)

Важно отметить следующее:

  • Eta Expansion — технология Scala, позволяющая использовать методы так же, как и функции
  • Технология была улучшена в Scala 3, чтобы быть почти полностью бесшовной

Ссылки:

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.