2015-07-06 59 views
7

Sto cercando di concatenare alcune funzioni di base utilizzando Future s restituite da un'azione slick e sto colpendo alcuni ostacoli piuttosto banali.Perché Future.onSuccess richiede una funzione parziale

Entrambi i metodi andThen e onSuccess richiedono un valore pari a PartialFunction passato come parametro. La mia comprensione è probabilmente abbastanza imperfetta, ma dopo aver letto circa anonymous functions sembra che lo andThen abbia bisogno di conoscere la funzione anonima per soddisfare qualsiasi input Success o Failure.

Dato onSuccess già solo si rivolge per il caso Success perché deve ancora essere un PartialFunction?

Questo blocco di codice i miei indicare il problema che sto avendo:

val db = Database.forConfig("h2mem1") 

try { 
    val f = db.run(setupCommands) 
    .onSuccess { println(_) } 

    Await.ready(f, 10.seconds) 
} 
finally db.close 

ottengo un errore di compilazione:

[error] found : Unit => Unit 
[error] required: PartialFunction[Unit,?] 
[error]   .onSuccess { println(_) } 
+1

@cmbaxter Ecco 'onComplete', non' onSuccess'. La mia ipotesi: coerenza con 'onFailure'. –

+0

2.11.6 - Questi [documenti] (http://www.scala-lang.org/files/archive/nightly/docs/library/index.html#scala.concurrent.Future) suggeriscono PartialFunction? – GoldenFish

+0

Penso che la domanda migliore sia perché "onComplete" non ha anche una funzione parziale? Penso che gli altri 3 siano stati messi in atto con effetti collaterali con le condizioni in mente e i PF sono buoni per la parte delle condizioni (corrispondenza del modello). Non sono sicuro del motivo per cui "onComplete" (sembra essere anche per effetto collaterale dato "Unità" come tipo di ritorno) non ha seguito l'esempio. – cmbaxter

risposta

3

Lo hanno fatto in modo da poter pattern match sul risultato, anche se sono d'accordo che sembra inutile, non ho davvero usare onSuccess e preferiscono map e flatMap miei futuri:

val f = Future.successful("test") 

    f.onSuccess({ 
    case "test" => println("Worked") 
    case x: String => println(s"Kind of worked: $x") 
    }) 

Nel caso di tipi di dati più avanzati ho potuto vedere questo essere più utile:

val fOpt = Future.successful(Option("Test")) 

    fOpt.onSuccess({ 
    case Some(x) => println(x) 
    case None => println("None") 
    }) 

in realtà questo è probabilmente solo venendo dal api attore da quando si ask un attore che non k ora il tipo di ritorno, è necessario far corrispondere modello su di esso dal momento che è Any:

val actor:ActorRef = ??? 

    val fAny = actor ? "asking" 

    fAny.onSuccess({ 
    case x:String => println(s"Something String $x") 
    case x:Int => println(s"Something Int $x") 
    case x => println(s"Something else $x") 
    }) 
+1

Tuttavia, è possibile utilizzare anche la sintassi di corrispondenza del modello per le normali funzioni. – Owen

+0

@Owen: Sì, è questo che mi imbarazza anche. Se voglio modellare la corrispondenza/passare una funzione parziale, posso farlo in qualsiasi momento. Perché abbiamo mai bisogno di PartialFunction come tipo di argomento? – kornfridge

1

Beh, si può semplicemente passare un PartialFunction, se ha bisogno di una :

db.run(setupCommands).onSuccess(PartialFunction(println)) 

Oppure:

db.run(setupCommands).onSuccess { case result => println(result) } 
+2

È solo un po 'inutile inelegante ... Sono sicuro che c'è un motivo per cui non vedo – GoldenFish