Domanda

Supponiamo che io sono un metodo session.get(str: String): String ma non so se lo restituirà una stringa o un valore nullo, perché viene da Java.

C'è un modo più semplice per trattare questa a Scala, invece di session.get("foo") == null? Forse qualche magia applicare come ToOption(session.get("foo")) e poi posso trattare in modo Scala come

ToOption(session.get("foo")) match {
    case Some(_) =>;
    case None =>;
}
È stato utile?

Soluzione

metodo Option Il compagno dell'oggetto apply serve come una funzione di conversione da riferimenti nullable:

scala> Option(null)
res4: Option[Null] = None

scala> Option(3)   
res5: Option[Int] = Some(3)

Altri suggerimenti

L'oggetto ha una Option applymethod che fa esattamente questo:

var myOptionalString = Option(session.get("foo"));

Si noti che quando si lavora con oggetti Java non funzionerà come previsto:

val nullValueInteger : java.lang.Integer = null
val option: Option[Int] = Option(nullValueInteger)
println(option)  // Doesn't work - zero value on conversion

val nullStringValue : String = null
val optionString: Option[String] = Option(nullStringValue)
println(optionString) // Works - None value

Questo è un argomento molto vecchio, ma una bella!

E 'vero che la conversione di qualsiasi risultato non eccezione di Prova a opzione si tradurrà in un Alcuni ...

scala> Try(null).toOption
res10: Option[Null] = Some(null)

... perché Prova non si tratta di controllo valori Null, ma solo un modo per gestire le eccezioni in modo funzionale.

Utilizzo di cercare di catturare un'eccezione e la conversione che per un opzione per comodità verranno visualizzati solo nel caso in cui nessuno un'eccezione accade.

scala> Try(1/0).toOption
res11: Option[Int] = None

Si vuole preservare i valori che vengono fuori prova. Che può essere nullo.

Ma è anche vero che la lib di serie è piuttosto confusa a volte ...

scala> Try(null).toOption
res12: Option[Null] = Some(null)

scala> Option(null)
res13: Option[Null] = None

Questo comportamento è un po 'incoerente, ma che tipo di riflette l'utilizzo di intented sia provare e l'opzione.

Si utilizza cercare di ottenere tutto ciò che esce da un'espressione che può generare eccezioni, e non si cura di fare un'eccezione per sé.

Il valore che può esca può benissimo essere nullo. Se toOption dato Nessuno, non si poteva distinzione fra un'eccezione e un null , e che non è abbastanza!

Standalone, si utilizza l'opzione di incapsulare l'esistenza o meno di qualcosa. Quindi, in questo caso, alcuni (null) vale None, e che abbia un senso, perché nulla in questo caso rappresenta l'assenza di qualcosa. Non c'è ambiguità.

E 'importante sottolineare che, in ogni caso referenziale trasparenza non è rotto dal .toOption è non la stessa opzione ()

Se si ha realmente bisogno di far rispettare ENTRAMBI sicurezza rispetto alle eccezioni e la sicurezza nullo, e il codice di davvero non ha bisogno di distinzione fra zero e un'eccezione , basta combinare entrambi i paradigmi! Perché beh, questo è ciò che si vuole, giusto?

Si può farlo in un modo ...

scala> Try(Option(null)).getOrElse(None)
res23: Option[Null] = None

scala> Try(Option(3/0)).getOrElse(None)
res24: Option[Int] = None

scala> Try(Option(3)).getOrElse(None)
res25: Option[Int] = Some(3)

... o in un altro ...

scala> Try(Option(null)).toOption.flatten
res26: Option[Null] = None

scala> Try(Option(3/0)).toOption.flatten
res27: Option[Int] = None

scala> Try(Option(3)).toOption.flatten
res28: Option[Int] = Some(3)

... o ridicolmente più brutto di loro anothers ...

scala> Option(Try(null).getOrElse(null))
res29: Option[Null] = None

scala> Option(Try(3/0).getOrElse(null))
res30: Option[Any] = None

scala> Option(Try(3).getOrElse(null))
res31: Option[Any] = Some(3)
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top