Falha rápida ao usar para compreensão com scala.util.Try
Eu realmente gostoscala.util.Try
no Scala 2.10, e como ele funciona para compreensão, torna fácil lidar com várias etapas que podem dar errado.
Por exemplo, poderíamos usar o seguinte código para garantir que apenas imprimimos dois números se e somente se tudo estiver sob controle e obtivermos valor corretamente.
def tryA: Try[Int] = {....}
def tryB: Try[Int] = {....}
for {
a <- tryA
b <- tryB
} {
println (s"We got:${a+b}")
}
Mas uma das minhas preocupações é que este código é na verdade ignorar quaisquer exceções, o que significa que se parece com o seguinte bloco try-cactch:
try {
// .....
} catch {
case _: Exception => // Swallow any exception
}
Tanto quanto sei, há um argumento de que esse tipo de código é um mau cheiro, porque ninguém notará que existe uma exceção.
O que eu gostaria de conseguir é que ainda usandofor
para se certificar de queprintln
execute somente se tudo estiver OK, mas se houver alguma exceção em qualquer etapa, ela explodirá e descartará a exceção diretamente.
Atualmente aqui é como eu faço isso, mas parece menos elegante porque introduz um novoTry[Unit]
objeto, então eu estou querendo saber como eu poderia fazer este código melhor?
Por exemplo, é possível se livrar doresult
variável eresult.get
declaração, mas ainda obter exceção sendo lançada?
def tryA: Try[Int] = {....}
def tryB: Try[Int] = {....}
val result = for {
a <- tryA
b <- tryB
} yield {
println (s"We got:${a+b}")
}
result.get
AtualizarPara tornar a coisa mais clara, é o resultado do Scala REPL do primeiro código nesta questão.
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>
Podemos ver que nada acontece aqui, mesmotryB
é umFailure
com exceção. O que eu gostaria de obter é uma exceção sendo lançada, e sem a introdução do novoTry[Unit]
objeto comyield
, Isso é possível?