Функции без аргументов, с единицей как аргумент в scala
def foo(x:Int, f:Unit=>Int) = println(f())
foo(2, {Unit => 3+4}
//case1
def loop:Int = 7
foo(2, loop) //does not compile
changing loop to
//case 2
def loop():Int = 7
foo(2, loop) // does not compile
changing loop to
//case 3
def loop(x:Unit): Int = 7 //changing according to Don Comments
foo(2,loop) // compiles and works fine
should'nt case 1 и case 2 также работают? почему они не работают?
определение foo как
def foo(x:Int, y:()=>Int)
то случай 2 работает, но не случай 1.
Arent, все они должны работать, определяя функции в любом случае.
//также я думаю() = > Int в foo - это плохой стиль, y: = > Int не работает, комментарии
Ответы
Ответ 1
Scala различает следующие вещи:
- Функции/методы без списков параметров ( "параметр по имени", если функция)
- Функции с одним пустым списком параметров
- Функции с одним параметром типа Unit
Ни один из них не эквивалентен, хотя в качестве удобства Scala можно исключить пустые списки параметров. (Кстати, два пустых списка параметров тоже не совпадают.)
Итак, даже если Unit
записано ()
, это не то же самое, что параметр функции parens ()
для функции или метода. Вместо этого подумайте ()
как Tuple0
.
Итак, если вы скажете f: Unit => Int
, то вы имеете в виду, что "f принимает один параметр, но он действительно скучный параметр, потому что он Unit
, который всегда должен быть тем же самым скучным Tuple0
value ()
", То, что вы пишете, действительно короткое для f: (Unit) => Int
.
Если вы скажете f: () => Int
, то вы имеете в виду, что "f не принимает никаких параметров и создает Int
".
Если вы скажете f: => Int
, то вы имеете в виду, что "задержка выполнения любой инструкции создает значение Int
, пока мы не используем ее в этом коде (и не переучитываем ее каждый раз)". Функционально это в основном совпадает с f: () => Int
(и внутренне преобразуется в тот же класс Function0
), но имеет другое использование, предположительно для более компактной формы замыканий (вы всегда опускаете =>
в вызывающем коде).
Ответ 2
() = > Int - это функция 0 [Int], в то время как Unit = > Int is Function1 [Unit, Int]
scala> val function0: () => Int = () => 5
function0: () => Int = <function0>
scala> val function1: Unit => Int = u => 5
function1: (Unit) => Int = <function1>
scala> function0()
res0: Int = 5
scala> function1("anything")
res1: Int = 5
scala> function1(100)
res2: Int = 5
scala>
Также обратите внимание, что() является объектом Unit
scala> function1(())
res11: Int = 5
scala> function1 ()
res12: Int = 5
scala> function1()
res13: Int = 5
scala> val unit = ()
unit: Unit = ()
scala> function1(unit)
res15: Int = 5
scala> function1 apply unit
res16: Int = 5
scala>
Ответ 3
В случае, если 1 и 2 выше, возвращаемое значение loop, а не loop, является типом для второго аргумента foo и fail: Int!= Unit = > Int
Изменение цикла имеет опечатку.