La convenzione è che il codice Scala non usa valori nulli (con un numero limitato di eccezioni, che dovrebbero essere immediatamente risolti quando si usano quelle funzioni di libreria).
Quindi, un valore di Scala è un segno che qualcosa è andato storto (almeno uno PBCAK), quindi si può anche lanciare un'eccezione. Questa non è un'operazione di routine; questa è una cosa seriamente incasinata. Cattura l'eccezione ovunque si rilevino gravi errori. La cattura di uno IllegalArgumentException
invece di uno NullPointerException
non aggiunge ulteriori informazioni. Lascia solo l'originale.
Se il codice proviene da Java, il modo canonico di gestirlo è di inserirlo in Option
, che convertirà null
in None
. Quindi probabilmente non hai nemmeno bisogno di lanciare un'eccezione; basta restituire un None
.
def myMethod(p: String) = Option(p).map(_.toLowerCase)
Se non è possibile continuare quando è nullo, è necessario considerare se un'eccezione informativa potrebbe essere d'aiuto. Option(p).orElse(throw new IllegalArgumentException("Null!"))
è un modo compatto per esprimere il sentimento di lancio delle eccezioni.
In Scala 2.10, è inoltre possibile eseguire il wrapping delle cose in scala.util.Try(...)
che catturerà e impacchetterà automaticamente l'eccezione per te. Se vuoi un'eccezione pacchettizzata invece di una generata, questa è la strada da percorrere.(E utilizzare Try
invece di Option
.)
import scala.util.Try
def myMethod(p: String) = Try(p.toLowerCase)
Infine, per la gestione più generale degli esiti alternativi, usare Either
. La convenzione per la gestione degli errori è che l'output previsto è un Right(whatever)
, mentre Left(whatever)
indica che qualcosa è andato storto.
fonte
2012-11-29 22:49:28
Dato che sto scrivendo un'API, penso il costrutto più appropriato è Try. – j3d
Fare attenzione quando si avvolgono valori null in un'opzione. Se ti affidi all'inferenza di tipo, a volte potresti incontrare dei problemi. Ad esempio, se fai Option (null) .map (_ + 1) otterrai un'esenzione. Tuttavia, fare Option (null: String) .map (_. ToLowerCase) va bene –