Scala'daki Option ile Java'da boş döndürme yöntemini sarmak?


107

Bir yöntemim olduğunu varsayalım, session.get(str: String): Stringancak size bir dize mi yoksa boş mu döndüreceğini bilmiyorsunuz, çünkü Java'dan geliyor.

Bunu Scala'da tedavi etmenin daha kolay bir yolu var mı session.get("foo") == null? Belki biraz sihir uygulanabilir ToOption(session.get("foo"))ve sonra ona Scala gibi davranabilirim

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

4
Daha fazla Seçenek numarası için blog.tmorris.net/scalaoption-cheat-sheet'e
Landei

4
Yukarıdaki bağlantı blog.tmorris.net/posts/scalaoption-cheat-sheet olmalıdır .
Jacek Laskowski

Yanıtlar:


182

OptionTamamlayıcı nesnenin applyyöntem null referanslardan bir dönüştürme fonksiyonu olarak hizmet eder:

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

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

19

OptionAmacı, sahip applytam olarak bu yöntem:

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

5

Java nesneleriyle çalışırken beklendiği gibi çalışmayacağına dikkat edin:

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

1
Scala 2.11.8 ile koştum. İkinci satır NullPointerException oluşturdu. Altıncı satır Beklediğiniz gibi Yok (Yok) değil Bazı (null) aldı.
John Lin

1. optionString'de Option yerine Some'ı kullandı - Orijinal yanıtta değiştirildi. 2. Yalnızca Scala 2.12.5'te doğrulandı
DekelM

-3

Bu çok eski bir konu ama güzel bir konu!

Try to Option'ın herhangi bir istisna dışı sonucunun dönüştürüldüğünde Some ...

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

... çünkü Try, boş değer atanabilirlik denetimi ile ilgili değil, istisnaları işlevsel olarak ele almanın bir yoludur.

Bir istisnayı yakalamaya çalışın kullanılması ve bunu kolaylık sağlamak için bir Seçeneğe dönüştürülmesi, yalnızca bir istisna olması durumunda Hiçbiri gösterecektir.

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

Try'dan çıkan değerleri korumak istiyorsunuz. Bu boş olabilir.

Ama standart kitaplığın bazen oldukça kafa karıştırıcı olduğu da doğrudur ...

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

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

Bu davranış biraz tutarsızdır, ancak hem Try hem de Option'ın amaçlanan kullanımını yansıtır.

İstisnalar fırlatabilecek bir ifadeden çıkan her şeyi almaya çalışın ve istisnanın kendisini umursamıyorsunuz.

Ortaya çıkabilecek değer çok iyi bir boş olabilir. Eğer toOption Hiçbiri verdiyse, bir istisna ile boş arasında ayrım yapamazsınız ve bu hoş değildir!

Bağımsız, bir şeyin varlığını ya da olmama durumunu özetlemek için Option'ı kullanırsınız. Bu durumda Bazı (null) Yoktur ve bu mantıklıdır, çünkü bu durumda null, bir şeyin yokluğunu temsil eder. Burada belirsizlik yok.

Herhangi bir durumda referans şeffaflığının bozulmadığını belirtmek önemlidir, çünkü .toOption Option () ile aynı değildir .

İKİ istisna güvenliğini VE boş güvenliği gerçekten uygulamanız gerekiyorsa ve kodunuzun gerçekten boş ve istisna arasında ayrım yapması gerekmiyorsa, her iki paradigmayı birleştirmeniz yeterlidir! Çünkü peki, istediğiniz bu, değil mi?

Bunu tek bir şekilde yapabilirsiniz ...

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)

... veya başkası ...

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)

... ya da gülünç derecede en çirkin olanları ...

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)
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.