Что такое расширение в Scala?
Я новичок в Скале. Я только что услышал термин "расширение eta" и грубо знаю, что это означает расширение метода до функционального объекта. Но я нахожу мало ресурсов в SO, которые систематически представляют его.
Мне интересно, как работает eta-расширение в Scala. Каковы сценарии, что это расширение необходимо? И как это расширение реализовано в Scala?
Я примерно знаю, что в таких случаях:
def someMethod(x: Int): Int = x * x
someMethod _
будет примерно переведен в новый объект функции, как это:
new Function1[Int, Int] {
def apply(x: Int): Int = x * x
}
Это все, что делает Scala?
1 ответ
Определение и некоторые примеры приведены в http://scala-lang.org/files/archive/spec/2.11/06-expressions.html.
someMethod _
будет примерно переведен в новый объект функции, как это:
Не совсем: это на самом деле
new Function1[Int, Int] {
def apply(x: Int): Int = someMethod(x)
}
Разница имеет значение, например, если someMethod
где-то переопределено.
Это все, что делает Scala?
Вам также необходимо учитывать, что происходит, если метод принимает несколько списков параметров (вы получаете функцию, которая возвращает функцию) или параметры по имени.
Каковы сценарии, что это расширение необходимо?
Когда вы специально просите об этом (например,
someMethod _
).При использовании метода (с параметрами), где ожидается значение типа функции (или типа SAM в Scala 2.12). Например
def foo(f: Int => Int) = ??? foo(someMethod)
Вот и все.
Обратите внимание, что используя eta-расширение и анонимную функцию с заполнителями (someMethod(_)
) может вести себя по-разному из-за вывода типа, последствий и т. д.
Расширение Eta На высоком уровне - это процесс преобразования методов в функции. Почему? Какой? Разве они не такие? Поясним:
метод в Скале, что мы знаем, какdef someMethodName(SomePramList): SomeReturnType
. Это начинается сdef
. У него может быть список параметров, а может быть и больше 1. Например:
def numAdder(num1: Int)(num2: Int): Int =
num1 + num2
функция, илиlambda
функция выглядит примерно так: (SomeParams) => SomeReturnType
. Например:
val aFunction: Int => Int => Int = (num1: Int) => (num2: Int) => num1 + num2
Что касается функций, важно понимать, что этот синтаксис в основном является синтаксическим сахаром для FunctionN.apply
метод.
Каковы сценарии, при которых требуется расширение eta?
Некоторые примеры:
Example1 - Применение метода внутри map
(или filter
, flatMap
так далее)
Написание такого кода:
def addPlus1(x: Int): Int = x + 1
List(1,2,3).map(addPlus1)
У компилятора должна быть функция внутриmap
. Итак, он преобразует данный метод в функцию:List(1,2,3).map(x => addPlus1(x))
. ЭтоEta expansion
.
Example2 - каррирование
При определении каррированного метода, например:
def numAdder(num1: Int)(num2: Int): Int =
num1 + num2
И они создают такую функцию, как:
val curriedFunction: Int => Int = numAdder(4)
//or
val curriedFunction2 = numAdder(4) _
Мы определили функцию вне метода. ЭтоEta expansion
.
Еще несколько примеров
Определен метод, который принимает значение функции:
def someMethod(f: () => Int): Int = f()
def method(): Int = 10
А затем запустите:
someMethod(method)
преобразует метод method
в функцию. ЭтоEta expansion