1) To jest po prostu bardziej poręczny go używać, zwłaszcza wewnątrz DSL:
def printAndGet[T](f: => T) = {
val res = f
println(res + " printed")
res
}
scala> :paste
// Entering paste mode (ctrl-D to finish)
val k = printAndGet {
val a = 5
5 * a
}
// Exiting paste mode, now interpreting.
25 printed
k: Int = 25
2) => T
może być tylko parametr metody lub funkcji. I rzeczywiście => T
i () => T
nie są wymienne:
scala> def aaa(f: => String) = f
aaa: (f: => String)String
scala> val a: Function1[() => String, String] = aaa _
<console>:8: error: type mismatch;
found : (=> String) => String
required: (() => String) => String
val a: Function1[() => String, String] = aaa _
^
Dzięki @ som-snytt, fоund ten:
scala> object O { def f(i: Int) = i; def f(i: => Int) = i + 1 }
defined object O
scala> O.f(5)
res12: Int = 5
scala> O.f(5: (=> Int))
<console>:1: error: no by-name parameter type allowed here
O.f(5: (=> Int))
^
Nawet ten, który powinien działać, jeśli kompiluje - ale tak nie jest (scala 2.11.2, 2.11.5 REPL tylko wywala):
scala> val k: (=> Int) => Int = O.f _
k: (=> Int) => Int = <function1>
scala> k(5) //should be 6
res18: Int = 5 //WTF?
Ostatnio jeden wydaje się błędem
3) Nie do końca, jeśli chcesz to samo, tylko konwertować => T
w () => T
:
scala> def aaa(f: => String) = {f _}
aaa: (f: => String)() => String
Bytecode mogą także różnić. Na przykład, kompilator będzie bardziej prawdopodobnie wbudowany w kod od => T
bez generowania dla niego lambda. Tak więc kluczową różnicą jest to, że () => T
jest w rzeczywistości obiektem (obywatelem pierwszej klasy), nie jest to => T
.
4) patrz 1, ale czasami może zajść potrzeba upewnienia się, że użytkownik wie, że obliczenia mogą być opóźnione - () => T
jest wtedy lepsza.
5) To część podpisu typu, wystarczy spojrzeć na eta-ekspansji:
scala> def aaa(f: => String) = {f}
aaa: (f: => String)String
scala> aaa _ //convert method into a function
res7: (=> String) => String = <function1>
scala> val a: (=> String) => String = aaa _
a: (=> String) => String = <function1>
Jednak scala nie rozpoznaje go jako niezależny typ:
scala> val a: Function1[(=> String), String] = aaa _
<console>:1: error: no by-name parameter type allowed here
val a: Function1[(=> String), String] = aaa _
^
Rozważmy następujący komentarz - https : //twitter.com/StewOConnor/status/633555338894020608 –