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.Integerna 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.Integerna Scalę Option[Int]?
Odpowiedzi:
Mieszacie Inti java.lang.Integertak 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, -Xlintaby zobaczyć ostrzeżenie dla val o!
Integerwywnioskowano `val x: Opcja [Int] = Opcja (i) .asInstanceOf [Opcja [Int]]`
To wydaje się dzieje dlatego, że tworzenie Optioni przekształcenie go do Intw 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 .
nulljako liczbę całkowitą. Jest to prawdopodobnie kac, z Cktórego można przypisać 0wskaźnik. Ale to nie znaczy, że wynikowy wskaźnik jest 0taki, więc przełączanie się między nimi jest niejasne C.
Integernajprawdopodobniej 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.
JavaConvertersraczej 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.