Даны три способа выражения одной и той же функции 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
. Вы просто не используете здесь вывод типов.
f1
- это function
, а f2
- это method
?
apply
. Метод, в общем, метод.
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)
a
неизменяема и вычисляется при инициализации, но b
остается изменяемым значением. Таким образом, ссылка на b
устанавливается во время инициализации, но значение, хранимое b
, остается изменяемым. Ради интереса теперь вы можете создать новый val b = 123
. После этого ваш a(5)
всегда будет давать 11, поскольку b
теперь является совершенно новым значением.
Выполнение определения, такого как def x = e, не приведет к оценке выражения e . Вместо этого e оценивается всякий раз, когда используется x . В качестве альтернативы Scala предлагает определение значения val x = e, который оценивает правую часть e как часть оценки определения. Если затем используется x , он немедленно заменяется на предварительно вычисленное значение e , так что выражение не нужно вычислять снова.
Scala на примере Автор: Мартин Одерски
Похожие вопросы
Связанные вопросы
Новые вопросы
scala
Scala - это язык программирования общего назначения, в основном предназначенный для виртуальной машины Java. Разработанный для краткого, элегантного и безопасного для типов представления общих шаблонов программирования, он сочетает в себе как императивный, так и функциональный стили программирования. Его ключевые особенности: продвинутая система статического типа с выводом типа; типы функций; сопоставления с образцом ; неявные параметры и преобразования; перегрузка оператора; полная совместимость с Java; совпадение
f1
в REPL показывает значение, статически связанное сf1
, в то время как оценкаf2
иf3
показывает результат вызывая эти методы. В частности, новый экземплярFunction1[Int, Int]
создается каждый раз при вызовеf2
илиf3
, аf1
остается неизменнымFunction1[Int, Int]
навсегда.