Sök…


Prova

Använd Try med map , getOrElse och flatMap :

import scala.util.Try

val i = Try("123".toInt)     // Success(123)
i.map(_ + 1).getOrElse(321)  // 124

val j = Try("abc".toInt)     // Failure(java.lang.NumberFormatException)
j.map(_ + 1).getOrElse(321)  // 321

Try("123".toInt) flatMap { i =>
  Try("234".toInt)
    .map(_ + i)
}                            // Success(357)

Använda Try med mönstermatchning:

Try(parsePerson("John Doe")) match {
    case Success(person) => println(person.surname)
    case Failure(ex) => // Handle error ...
}

Antingen

Olika datatyper för fel / framgång

def getPersonFromWebService(url: String): Either[String, Person] = {
    
    val response = webServiceClient.get(url)

    response.webService.status match {
        case 200 => {
            val person = parsePerson(response)
            if(!isValid(person)) Left("Validation failed")
            else Right(person)
        }

        case _ => Left(s"Request failed with error code $response.status")
    }
}

Mönstermatchning på antingen värde

getPersonFromWebService("http://some-webservice.com/person") match {
    case Left(errorMessage) => println(errorMessage)
    case Right(person) => println(person.surname)
}

Konvertera antingen värde till alternativ

val maybePerson: Option[Person] = getPersonFromWebService("http://some-webservice.com/person").right.toOption

Alternativ

Användningen av null avskräcks starkt, såvida inte interagerar med den äldre Java-koden som förväntar sig null . I stället bör Option användas när resultatet av en funktion antingen kan vara något ( Some ) eller ingenting ( None ).

Ett try-catch-block är mer lämpligt för felhantering, men om funktionen på ett legitimt sätt kan returnera ingenting är Option lämpligt att använda och enkelt.

Ett Option[T] kan antingen vara Some(value) (innehåller ett värde av typ T ) eller None :

def findPerson(name: String): Option[Person]

Om ingen person hittas kan None returneras. Annars returneras ett objekt av typen Some innehåller ett Person objekt. Följande är sätt att hantera ett objekt av typen Option .

Mönstermatchning

findPerson(personName) match {
    case Some(person) => println(person.surname)
    case None => println(s"No person found with name $personName")
}

Med hjälp av karta och getOrElse

val name = findPerson(personName).map(_.firstName).getOrElse("Unknown")
println(name) // Prints either the name of the found person or "Unknown"

Använd veck

val name = findPerson(personName).fold("Unknown")(_.firstName)
// equivalent to the map getOrElse example above.

Konvertera till Java

Om du behöver konvertera en Option till en null-kapabel Java-typ för interoperabilitet:

val s: Option[String] = Option("hello")
s.orNull           // "hello": String
s.getOrElse(null)  // "hello": String

val n: Option[Int] = Option(42)
n.orNull           // compilation failure (Cannot prove that Null <:< Int.)
n.getOrElse(null)  // 42

Hantera fel med ursprung i framtiden

När ett exception kastas från en Future kan du (bör) använda recover att hantera det.

Till exempel,

def runFuture: Future = Future { throw new FairlyStupidException }

val itWillBeAwesome: Future = runFuture

... kommer att kasta ett Exception från Future . Men eftersom vi kan förutsäga att ett Exception av typen FairlyStupidException med stor sannolikhet, kan vi specifikt hantera detta fall på ett elegant sätt:

val itWillBeAwesomeOrIllRecover = runFuture recover { 
    case stupid: FairlyStupidException => 
         BadRequest("Another stupid exception!") 
}

Som du kan se är metoden som givits för att recover en PartialFunction över domänen för alla Throwable , så att du kan hantera bara några få typer och sedan låta resten gå in i etern för undantagshantering på högre nivåer i Future stacken.

Observera att detta liknar köra följande kod i ett icke- Future sammanhang:

def runNotFuture: Unit = throw new FairlyStupidException

try {
    runNotFuture
} catch {
    case e: FairlyStupidException => BadRequest("Another stupid exception!")
}

Det är verkligen viktigt att hantera undantag som genereras inom Future för mycket av tiden är de mer lumska. De får inte alla i ditt ansikte vanligtvis eftersom de körs i ett annat utförande-sammanhang och tråd, och därför uppmanar dig inte att fixa dem när de händer, särskilt om du inte märker något i loggar eller beteendet hos Ansökan.

Använda try-catch klausuler

Förutom funktionella konstruktioner som Try , Option och Either för felhantering stöder Scala också en syntax som liknar Java, med hjälp av en try-catch-klausul (med en potentiell slutlig block också). Fångstklausulen är en mönstermatchning:

try { 
  // ... might throw exception
} catch {
  case ioe: IOException => ... // more specific cases first
  case e: Exception => ...
  // uncaught types will be thrown
} finally {
  // ...
}

Konvertera undantag till antingen eller alternativstyper

Om du vill konvertera undantag till Either eller Option kan du använda metoder som finns i scala.util.control.Exception

import scala.util.control.Exception._

val plain = "71a"
val optionInt: Option[Int] = catching(classOf[java.lang.NumberFormatException]) opt { plain.toInt }
val eitherInt = Either[Throwable, Int] = catching(classOf[java.lang.NumberFormatException]) either { plain.toInt }


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow