val i: java.lang.Integer = null
val o: Option[Int] = Option(i) // This yields Some(0)
Jaki jest bezpieczny sposób konwersji null: java.lang.Integer
na Scalę Option[Int]
?
val i: java.lang.Integer = null
val o: Option[Int] = Option(i) // This yields Some(0)
Jaki jest bezpieczny sposób konwersji null: java.lang.Integer
na Scalę Option[Int]
?
Odpowiedzi:
Mieszacie Int
i java.lang.Integer
tak dalej
val i: java.lang.Integer = null
val o: Option[Int] = Option(i)
pośrednio konwertuje na
val o: Option[Int] = Option(Integer2int(i))
który staje się
val o: Option[Int] = Option(null.asInstanceOf[Int])
a zatem
val o: Option[Int] = Some(0)
Jeśli chcesz pracować java.lang.Integer
, napisz
val o: Option[java.lang.Integer] = Option(i)
// o: Option[Integer] = None
Option[Integer](i).map(_.intValue)
wydaje mi się najbardziej idiomatyczny, ponieważ mówi, co robi. Użyj także, -Xlint
aby zobaczyć ostrzeżenie dla val o
!
Integer
wywnioskowano `val x: Opcja [Int] = Opcja (i) .asInstanceOf [Opcja [Int]]`
To wydaje się dzieje dlatego, że tworzenie Option
i przekształcenie go do Int
w jednym kroku (@ MarioGalic za odpowiedź wyjaśnia, dlaczego tak się dzieje).
Robi to, co chcesz:
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
. Wydaje mi się, że zapisuje tylko konwersję.
Wcześniej ten sam problem. To wątpliwe zachowanie jest znane zespołowi Scali. Wygląda na to, że zmiana go psuje coś innego. Zobacz https://github.com/scala/bug/issues/11236 i https://github.com/scala/scala/pull/5176 .
null
jako liczbę całkowitą. Jest to prawdopodobnie kac, z C
którego można przypisać 0
wskaźnik. Ale to nie znaczy, że wynikowy wskaźnik jest 0
taki, więc przełączanie się między nimi jest niejasne C
.
Integer
najprawdopodobniej pochodzi z kodu Java, więc „nie traktuj wartości null jako liczby całkowitej” nie jest praktyczną radą. I jawnie sprawdzamy tę liczbę całkowitą pod kątem używania zerowalności Option.apply
. Otrzymujemy więc nieoczekiwany wynik bez jawnego wykonywania niebezpiecznych operacji.
JavaConverters
raczej niż JavaConversion
)
theInteger.intValue()
. Uniknięcie tej awarii kosztuje dodatkowe sprawdzenie środowiska wykonawczego. W starszych wersjach Scali ta konwersja rzeczywiście spowodowała powstanie NPE; został zgłoszony jako błąd i naprawiony do bieżącego zachowania. Nie jestem ekspertem Scala, ale wykopałem scala-dev # 355 i scala # 5176 jako kontekst historyczny.