Ricerca…


Provare

Usando Prova con map , getOrElse e 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)

Uso di Try con corrispondenza del modello:

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

O

Diversi tipi di dati per errore / successo

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")
    }
}

Pattern matching su entrambi i valori

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

Converti un valore in Opzione

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

Opzione

L'uso di valori null è fortemente sconsigliato, a meno che non si interagisca con il codice Java legacy che si aspetta null . Invece, Option dovrebbe essere usato quando il risultato di una funzione potrebbe essere qualcosa ( Some ) o nothing ( None ).

Un blocco try-catch è più appropriato per la gestione degli errori, ma se la funzione potrebbe legittimamente non restituire nulla, Option è appropriato da usare e semplice.

Option[T] può essere Some(value) (contiene un valore di tipo T ) o None :

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

Se nessuna persona viene trovata, None può essere restituita. Altrimenti, viene restituito un oggetto di tipo Some contenente un oggetto Person . Quello che segue sono i modi per gestire un oggetto di tipo Option .

Pattern Matching

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

Utilizzando la mappa e getOrElse

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

Usando la piega

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

Conversione in Java

Se è necessario convertire un tipo di Option in un tipo Java null-enabled per l'interoperabilità:

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

Gestione degli errori originati nei futures

Quando exception viene lanciata dall'interno di un Future , puoi (dovresti) utilizzare recover per gestirlo.

Per esempio,

def runFuture: Future = Future { throw new FairlyStupidException }

val itWillBeAwesome: Future = runFuture

... genererà Exception dall'interno del Future . Ma visto che siamo in grado di prevedere che un Exception di tipo FairlyStupidException con una probabilità alta, siamo in grado di gestire questo specifico caso in modo elegante:

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

Come puoi vedere il metodo dato per recover è una PartialFunction sul dominio di tutti i Throwable , quindi puoi gestire solo alcuni tipi e lasciare che il resto entri nell'etere della gestione delle eccezioni a livelli più alti nello stack Future .

Si noti che questo è simile all'esecuzione del seguente codice in un contesto non Future :

def runNotFuture: Unit = throw new FairlyStupidException

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

È molto importante gestire le eccezioni generate all'interno di Future perché per la maggior parte del tempo sono più insidiose. Di solito non riescono a scappare, perché corrono in un contesto di esecuzione e thread diversi, e quindi non ti chiedono di correggerli quando accadono, specialmente se non noti nulla nei log o il comportamento del applicazione.

Usando le clausole try-catch

Oltre ai costrutti funzionali come Try , Option e Either per la gestione degli errori, Scala supporta anche una sintassi simile a quella di Java, utilizzando una clausola try-catch (con un potenziale blocco finally). La clausola catch è un pattern match:

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

Convertire le eccezioni in entrambi i tipi di opzioni

Per convertire le eccezioni in tipi Either o Option , è possibile utilizzare i metodi forniti in 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
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow