2016-10-29 3 views
1

Tenir compte d'une fonction définie f cette façon:laissant un minimum de code à l'intérieur essayer de bloquer

def f() = { 
    try { g(h()) } 
    catch { case _: E => j() } 
} 

Les fonctions g, h et j pourrait en fait être un code/expression.

Considérant que seulement h peut lancer des exceptions de type E, comment peut-f être réécrite de sorte que seul h est laissé à l'intérieur du bloc try?

Répondre

2

Vous pouvez utiliser scala.util.Try à la place. programme simple je l'ai testé dans ideone:

import scala.util.Try 
object Main extends App { 
    def f() = { 
     Try(h()).map(g).recover { case _: Exception => j() }.get 
    } 

    def g(x: Any) = "g:" + x 
    def h(): Any = throw new RuntimeException 
    def j() = "caught" 

    println(f()) // should print "g:caught" 
} 

Honnêtement, je ne voudrais pas écrire du code qui se termine par .get (au lieu, je propagerait la Try tout au long de la base de code, si je suis en train d'écrire un code qui peut lancer des exceptions) mais cela ne devrait être à peu près équivalent à votre exemple.

+0

Merci, mais je pense que votre réponse mérite une critique. Notez que dans ma question, en cas d'exception, f renvoie la valeur de j sans passer à g. De toute façon, votre réponse semble prometteuse! ;-) – erdavila

0

Si Scala try bloc pourrait avoir un else bloc - comme Python - une définition propre de f pourrait être écrit ainsi:

def f() = 
    try { h() } 
    catch { case _: E => j() } 
    else { v => g(v) } // v is the resulting value from the try block 

Malheureusement, Scala ne supporte pas une telle chose.


Cela pourrait être un - peut-être pas si propre - solution possible:

def f() = { 
    val u = 
    try { Some(h()) } 
    catch { case _: E => None } 

    u match { 
    case Some(v) => g(v) 
    case None => j() 
    } 
} 
3
Try { h() } match { 
    case Sucess(x) => g(x) 
    case _ => j() 
} 
1
def f() = Try(h()).map(g).getOrElse(j()) 

map sur votre résultat Try. g() sera appelée uniquement sur Success(). Utilisez getOrElse() pour indiquer une valeur par défaut sur Failure().

import scala.util.Try 

def h() = if (util.Random.nextBoolean) 7 else throw new Error 
def g(x:Int) = x*5 
def j() = 11 

Try(h()).map(g).getOrElse(j()) // returns 35 or 11