Я немного запутался в использовании параметров вызова по имени в Scala. Пожалуйста, помогите мне понять, что здесь происходит. Рассмотрим следующий пример использования параметра вызова по имени:
def param = {println("Param evaluates"); 40}
def lazyEval(x: => Int) = {
println("lazy");
x
}
val s = lazyEval(param + 2)
// s = 42
У меня есть несколько вопросов, связанных друг с другом по этому поводу:
Метод
lazyEval
ожидает параметр типа=> Int
, так почему же операцияparam + 2
допустима? Почему мы можем добавить целое число 2 к объекту с типом=> Int
(в моем понимании под капотом это<function0>
) при вызове методаlazyEval
? Как мне подсказывает IDE, функцияlazyEval
ожидает параметр типаInt
вместо=> Int
(какого черта?).Почему после изменения типа обратного вызова с
=> Int
на() => Int
код не компилируется? Это 2 типа разные? Хотя короткая версия ('=> Int') - это просто синтаксический сахар.Немного поигравшись с кодом, я, наконец, смог изменить код, чтобы он компилировался с
() => Int
. Этот способ для меня более интуитивен.
.
def param = {println("Param evaluates"); 40}
def lazyEval(x: () => Int) = { // changed type to '() => Int'
println("lazy");
x() // explicitly calling function using parentheses '()'
}
val s = lazyEval(param _) // adding underscore after method name and removing `+2`
Чем эта версия отличается от первой (с типом обратного вызова => Int
)? Почему в этой версии нельзя сделать сложение целого числа со значением 2
и функцию param
(имею в виду thislazyEval(param _ + 2)
)? А что означает подчеркивание после имени метода? (Думаю, раньше он передавал сам метод, а не возвращаемое значение)
Спасибо в помощи