Primo caso,
save(throw new RuntimeException("boom!")) _
Secondo "Scala Reference" (§6.7), posteriore sottolineatura viene utilizzata al posto della lista degli argomenti, e l'espressione viene convertito
val f: (Boolean) => Unit = save(throw new RuntimeException("boom!"))
dove la prima argomento di def save
viene valutato immediatamente.
L'espressione e _ è ben formata se e è di tipo metodo o se E è un parametro chiamata per nome. Se e è un metodo con parametri, e _ rappresenta e convertito in un tipo di funzione dall'espansione eta (§6.26.5). Se e è un metodo senza parametro o parametro per nome di tipo => T, e _ rappresenta la funzione di tipo() => T, che valuta e quando viene applicata all'elenco di parametri vuoto () .
Per rendere le cose funzionano come ci si aspetta, sono necessarie alcune modifiche:
scala> def save(f:() => Any)(run:Boolean) { if (run) { println("running f"); f() } else println("not running f") }
save: (f:() => Any)(run: Boolean)Unit
scala> val f = save(() => throw new RuntimeException("boom!")) _
f: (Boolean) => Unit = <function1>
scala> f(true)
running f
java.lang.RuntimeException: boom!
at $anonfun$1.apply(<console>:6)
Secondo caso,
save(throw new RuntimeException("boom!"))(_)
Secondo "Scala Reference" (§6.23), quando è segnaposto utilizzato come sostituto di un argomento, l'espressione viene convertita in
val f: (Boolean) => Unit = save(throw new RuntimeException("boom!"))(_)
fonte
2011-02-07 09:31:39
Puoi trovare alcune spiegazioni qui: http://stackoverflow.com/questions/2363013/in-scala-why-cant-i-partially-apply-a-function-without-explicitly-specifying-it –
IMHO, questo è un bug –