Scala Seçeneği (null) Hiçbiri olarak bekleniyordu ama bazılarını aldım


Yanıtlar:


19

Sen karıştırma edilir Intve java.lang.Integerböylece

val i: java.lang.Integer = null
val o: Option[Int] = Option(i)

dolaylı olarak

val o: Option[Int] = Option(Integer2int(i))

hangisi olur

val o: Option[Int] = Option(null.asInstanceOf[Int])

Böylece

val o: Option[Int] = Some(0)

Eğer çalışmak istiyorsanız java.lang.Integer, o zaman yazın

val o: Option[java.lang.Integer] = Option(i)
// o: Option[Integer] = None

2
Bu yakın zamanda bir yerde istendi, bu yüzden gerçek bir yakaladım. Belki de sorun çıkarımdadır: Option[Integer](i).map(_.intValue)benim için en deyimsel görünüyor, çünkü ne yaptığını söylüyor. Ayrıca, -Xlintiçin uyarı görmek için kullanın val o!
som-snytt

Boks gidiş dönüşünden kaçınmak için `val x: Option [Int] = Option (i) .asInstanceOf [Option [Int]]` olduğu Integerhesaplanır.
som-snytt

7

Bu oluyor gibi görünüyor çünkü siz Optiononu yaratıyorsunuz ve Intbir adımda dönüştürüyorsunuz (@ MarioGalic'in cevabı bunun neden olduğunu açıklıyor).

İstediğinizi yapar:

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)

Diğer cevapta önerdim _.intValue. Ben sadece dönüşüm çağrısını kaydeder sanırım.
som-snytt

1

Daha önce aynı sorunla karşı karşıya kaldık. Bu şüpheli davranış Scala ekibi tarafından bilinir. Görünüşe göre onu değiştirmek başka bir yerde bir şeyleri kırar. Bkz. Https://github.com/scala/bug/issues/11236 ve https://github.com/scala/scala/pull/5176 .


2
Gerçekten şüpheli davranış nullbir tamsayı olarak davranmaktır . Bu muhtemelen bir işaretçiye Catamanın 0uygun olduğu bir akşamdan kalmadır. Ancak bu, ortaya çıkan işaretçinin olduğu anlamına gelmez 0, bu yüzden ikisi arasında geçiş yapmak çok tehlikeli C.
Tim

Integerbüyük olasılıkla Java kodundan geldi, bu yüzden 'null değerini tamsayı olarak ele alma' işlem yapılabilir bir tavsiye değildir. Ve açıkça kullanarak bu Tamsayıyı nullability için kontrol ediyoruz Option.apply. Bu nedenle, herhangi bir güvenli olmayan işlem yapmadan beklenmedik çıktılar elde ederiz.
simpadjo

Mesele şu ki, temel neden Java olduğunda Scala'yı "şüpheli davranış" için suçlayamazsınız. İşlem yapılabilir öneri, örtük dönüşüm kullanmak yerine Java türlerinden eşdeğer Scala türlerine açık dönüşüm sağlamaktır. (Bundan JavaConvertersziyade JavaConversion)
Tim

1
Bu durumda derleme hatası / uyarısı yaymadığı için Scala'yı suçlayabilirim. Çalışma zamanı çökmesi bile daha iyi olurdu. Sadece şirketimde bile Scala'da 5 yıldan fazla deneyime sahip 2 geliştirici bu sorunu vurdu.
simpadjo

1
@Zaman Sadece arayarak bir çalışma zamanı çökmesi almak çok kolay olurdu theInteger.intValue(). Bu çökmeyi önlemek ekstra çalışma zamanı kontrolüne mal olur. Scala'nın eski versiyonlarında, bu dönüşüm gerçekten bir NPE üretti; bir hata olarak rapor edildi ve mevcut davranışa sabitlendi. Ben bir Scala uzmanı değilim, ama tarihsel bağlam olarak scala-dev # 355 ve scala # 5176'yı kazdım .
amalloy
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.