Ini adalah topik yang sangat lama tapi bagus!
Memang benar bahwa mengubah hasil Non-pengecualian dari Try to Option akan menghasilkan Beberapa ...
scala> Try(null).toOption
res10: Option[Null] = Some(null)
... karena Try bukan tentang pemeriksaan nullability tetapi hanya cara untuk menangani pengecualian secara fungsional.
Menggunakan Coba untuk menangkap pengecualian dan mengubahnya menjadi Opsi untuk kenyamanan hanya akan menampilkan Tidak Ada jika terjadi pengecualian.
scala> Try(1/0).toOption
res11: Option[Int] = None
Anda ingin melestarikan nilai-nilai yang keluar dari Try. Itu mungkin nol.
Tetapi juga benar bahwa lib standar terkadang cukup membingungkan ...
scala> Try(null).toOption
res12: Option[Null] = Some(null)
scala> Option(null)
res13: Option[Null] = None
Perilaku ini agak tidak konsisten tetapi ini mencerminkan penggunaan yang diinginkan dari Try dan Option.
Anda menggunakan mencoba untuk mendapatkan apa pun yang keluar dari ekspresi yang mungkin memunculkan pengecualian, dan Anda tidak peduli dengan pengecualian itu sendiri.
Nilai yang mungkin keluar mungkin saja nol. Jika toOption memberikan Tidak ada, Anda tidak dapat membedakan antara pengecualian dan nol , dan itu tidak cantik!
Mandiri, Anda menggunakan Option untuk merangkum ada atau tidaknya sesuatu. Jadi dalam kasus itu Some (null) is None, dan itu masuk akal, karena null dalam kasus itu mewakili tidak adanya sesuatu. Tidak ada ambiguitas di sini.
Penting untuk diperhatikan bahwa dalam hal apapun transparansi referensial tidak rusak karena .toOption tidak sama dengan Option ()
Jika Anda benar-benar perlu menegakkan KEDUA keamanan pengecualian DAN keamanan nol, dan kode Anda benar-benar tidak perlu membedakan antara nol dan pengecualian , Anda hanya perlu menggabungkan kedua paradigma! Karena yah, itu yang kamu inginkan, bukan?
Anda dapat melakukannya dengan satu cara ...
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)
... atau lainnya ...
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)
... atau yang paling jelek dari mereka yang lain ...
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)