Различия между этими тремя способами определения функции в 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 предлагает определение стоимости вал x = e, который оценивает правую сторону e в рамках оценки из определения. Если x после этого использовано затем, оно немедленно заменено предварительно вычисленный значение e, Так что выражение не нужно вычислять снова.
Scala На Примере на Мартин Одерский