Mi piace molto lo scala.util.Try
in Scala 2.10 e il suo funzionamento con la comprensione rende la gestione di più passaggi che potrebbero andare storto facilmente.Errore rapido quando si usa la comprensione per scala.util.Try
Ad esempio, potremmo usare il seguente codice per assicurarci di stampare solo due numeri se e solo se tutto è sotto controllo e il valore viene correttamente ottenuto.
def tryA: Try[Int] = {....}
def tryB: Try[Int] = {....}
for {
a <- tryA
b <- tryB
} {
println (s"We got:${a+b}")
}
Ma una delle mia preoccupazione è che questo codice è in realtà ignora tutte le eccezioni, il che significa che ha il seguente blocco try-cactch:
try {
// .....
} catch {
case _: Exception => // Swallow any exception
}
Per quanto ne so, non c'è un argomento che questo tipo di codici è un cattivo odore, perché nessuno noterà che si verifica un'eccezione.
Quello che vorrei realizzare è che ancora utilizzando for
per assicurarsi che il println
eseguire solo se tutto è OK, ma se non v'è alcuna eccezione in tutte le fasi, si farà saltare in aria e buttare fuori l'eccezione direttamente.
Attualmente ecco come faccio questo, ma sembra meno elegante perché introduce un nuovo oggetto Try[Unit]
, quindi mi chiedo come potrei rendere questo codice migliore?
Ad esempio, è possibile eliminare la variabile result
e l'istruzione result.get
, ma viene comunque generata un'eccezione?
def tryA: Try[Int] = {....}
def tryB: Try[Int] = {....}
val result = for {
a <- tryA
b <- tryB
} yield {
println (s"We got:${a+b}")
}
result.get
Aggiornamento
Per rendere più chiaro cosa, è il risultato da Scala REPL del primo codice in questa domanda.
scala> def tryA: Try[Int] = Success(1)
tryA: scala.util.Try[Int]
scala> def tryB: Try[Int] = Failure(new Exception("error"))
tryB: scala.util.Try[Int]
scala> for {
| a <- tryA
| b <- tryB
| } {
| println (s"We got:${a+b}")
| }
scala>
Possiamo vedere che non succede nulla qui, anche tryB
è un Failure
con un'eccezione. Quello che vorrei ottenere è un'eccezione generata e senza l'introduzione del nuovo oggetto Try[Unit]
con yield
, è possibile?
Il tipo 'println' è' Unit', quindi 'result' genererà un'eccezione o restituirà il valore' Unit', '()'. –
No, non genererà un'eccezione a meno che non utilizzi il metodo 'get'. –
Il codice di esempio include un 'result.get' incondizionato. (Intendevo scrivere 'result.get' nel mio primo commento ...) –