Различия между этими тремя способами определения функции в 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>
3 ответа
f1
это функция, которая принимает целое число и возвращает целое число
f2
это метод с нулевой арностью, который возвращает функцию, которая принимает целое число и возвращает целое число. (Когда вы печатаете f2
позже REPL становится вызовом метода f2
.)
f3
такой же как f2
, Вы просто не используете там вывод типа.
Внутри класса, 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)
Выполнение определения, такого как def x = e, не будет оценивать выражение e. Вместо этого e оценивается всякий раз, когда используется x. В качестве альтернативы Scala предлагает определение значенияval x = e, которое оценивает правую часть e как часть оценки определения. Если затем затем используется x, он немедленно заменяется предварительно вычисленным значением e, так что выражение не нужно вычислять снова.
Scala на примере Мартина Одерского