val i: java.lang.Integer = null
val o: Option[Int] = Option(i) // This yields Some(0)
Qual è il modo sicuro per convertire null: java.lang.Integer
in Scala Option[Int]
?
val i: java.lang.Integer = null
val o: Option[Int] = Option(i) // This yields Some(0)
Qual è il modo sicuro per convertire null: java.lang.Integer
in Scala Option[Int]
?
Risposte:
Stai mescolando Int
e java.lang.Integer
così
val i: java.lang.Integer = null
val o: Option[Int] = Option(i)
si converte implicitamente in
val o: Option[Int] = Option(Integer2int(i))
che diventa
val o: Option[Int] = Option(null.asInstanceOf[Int])
così
val o: Option[Int] = Some(0)
Se vuoi lavorare con java.lang.Integer
, allora scrivi
val o: Option[java.lang.Integer] = Option(i)
// o: Option[Integer] = None
Option[Integer](i).map(_.intValue)
sembra molto idiomatico, dal momento che dice cosa sta facendo. Inoltre, utilizzare -Xlint
per visualizzare l'avviso per il val o
!
Integer
viene inferito.
Questo sembra accadere perché stai creando Option
e convertendolo in un Int
unico passaggio (la risposta di @ MarioGalic spiega perché questo sta accadendo).
Questo fa quello che vuoi:
scala> val o: java.lang.Integer = null
o: Integer = null
scala> val i: Option[Int] = Option(o).map(_.toInt)
i: Option[Int] = None
scala> val o1: java.lang.Integer = 1
o1: Integer = 1
scala> val i1: Option[Int] = Option(o1).map(_.toInt)
i1: Option[Int] = Some(1)
_.intValue
. Immagino che salvi solo la chiamata di conversione.
Di fronte allo stesso problema prima. Questo comportamento discutibile è noto al team Scala. Sembra che cambiarlo si rompa qualcosa altrove. Vedi https://github.com/scala/bug/issues/11236 e https://github.com/scala/scala/pull/5176 .
null
come un numero intero. Questo è presumibilmente una sbronza da C
cui è OK assegnare 0
a un puntatore. Ma questo non significa che il puntatore risultante sia 0
, quindi è sconsigliabile passare da uno all'altro C
.
Integer
molto probabilmente proviene dal codice Java, quindi "non trattare null come un numero intero" non è un consiglio attuabile. E controlliamo esplicitamente questo numero intero per nullità usando Option.apply
. In questo modo otteniamo output imprevisti senza fare esplicitamente operazioni non sicure.
JavaConverters
piuttosto che JavaConversion
)
theInteger.intValue()
. Evitare l'incidente è ciò che costa un controllo di runtime aggiuntivo. Nelle versioni precedenti di Scala, questa conversione ha effettivamente prodotto un NPE; è stato segnalato come un bug e corretto per il comportamento corrente. Non sono un esperto di Scala, ma ho scavato scala-dev # 355 e scala # 5176 come contesto storico.