Различия между этими тремя способами определения функции в Scala
Учитывая три способа выражения одной и той же функции f(a) := a + 1
:
val f1 = (a:Int) => a + 1
def f2 = (a:Int) => a + 1
def f3:(Int => Int) = a => a + 1
Как эти определения различаются? REPL не указывает на очевидные отличия:
scala> f1
res38: (Int) => Int = <function1>
scala> f2
res39: (Int) => Int = <function1>
scala> f3
res40: (Int) => Int = <function1>
Ответы
Ответ 1
f1
- это функция, которая принимает целое число и возвращает целое число.
f2
- это метод с нулевой активностью, который возвращает функцию, которая принимает целое число и возвращает целое число. (Когда вы набираете f2
в REPL позже, он становится вызовом метода f2
.)
f3
совпадает с f2
. Вы просто не используете там вывод типа.
Ответ 2
Внутри класса val
оценивается при инициализации, а def
оценивается только тогда, когда и каждый раз вызывается функция. В приведенном ниже коде вы увидите, что x оценивается при первом использовании объекта, но не снова при доступе к члену x. Напротив, y не оценивается, когда объект создается, но оценивается каждый раз, когда к нему обращаются.
class A(a: Int) {
val x = { println("x is set to something"); a }
def y = { println("y is set to something"); a }
}
// Prints: x is set to something
val a = new A(1)
// Prints: "1"
println(a.x)
// Prints: "1"
println(a.x)
// Prints: "y is set to something" and "1"
println(a.y)
// Prints: "y is set to something" and "1"
println(a.y)
Ответ 3
Выполнение определения, такого как def x = e, не будет оценивать выражение e. Вместо этого e оценивается всякий раз, когда используется x. Альтернативно, Scala предлагает определение стоимости
val x = e, который оценивает правую часть e как часть оценки
определения. Если затем используется x, оно немедленно заменяется
предварительно вычисленное значение e, так что выражение не нужно снова оценивать.
Scala Пример Мартин Одерский