Функция Литеральная ссылка на val и def
Я пытаюсь понять принципиальную разницу между этими двумя подходами ссылки / определения Function Literal
(ссылка на anonymous function
):
От val
scala> val v2 = new Function[Int, Int] {
| def apply(a: Int): Int = a + 1
| }
v2: Int => Int = <function1>
И по def
scala> def f2 = new Function[Int, Int] {
| def apply(a: Int): Int = a + 1
| }
f2: Int => Int
Кажется, что это почти то же самое с точки зрения использования. Я либо могу пройти v2
или же f2
к функции, которая принимает (Int) => Int
в качестве аргумента. Передав аргументы своему..
Я думаю, или в случае v2 это создает Function1
объект, который относится к Function1
объект.. как proxy
?
Хорошо.. Мой вопрос: в чем преимущества и недостатки 1-го и 2-го подхода?
И это определяется def
Это все еще Function Literal
?
1 ответ
Прежде всего, ни один из ваших примеров на самом деле не является функциональным литералом - вы создаете Function
Например, обычным способом без сахара, и на самом деле вы можете использовать этот подход (new Function { ... }
) создать экземпляр scala.Function
из кода Java.
Ниже приведены оба функциональных литерала, которые в точности соответствуют вашим определениям:
val v2 = (a: Int) => a + 1
def f2 = (a: Int) => a + 1
Единственная реальная разница здесь в том, что val
создаст один экземпляр раз и навсегда, независимо от того, сколько раз вы используете v2
(и даже если вы никогда не используете его), в то время как def
будет каждый раз создавать новый экземпляр (или не создавать его вообще, если вы его никогда не используете). Так что вы, как правило, хотите пойти с val
,
Однако есть случаи, когда вам нужно использовать def
, Учтите следующее:
def myIdentity[A] = (a: A) => a
Мы никак не могли бы написать это как val
Так как Scala не имеет полиморфных функций в этом смысле (для любого случая Function[A, B]
, A
а также B
должны быть конкретные типы). Но мы можем определить полиморфный метод, который возвращает функцию, и когда мы пишем, например, myIndentity(1)
, A
будет выведено, чтобы быть Int
и мы создадим (и применим) Function[Int, Int]
точно так, как вы ожидаете.