Це дуже стара тема, але приємна!
Це правда, що перетворення будь-якого не виключення результату "Спроба до варіанту" призведе до деякого ...
scala> Try(null).toOption
res10: Option[Null] = Some(null)
... тому що спробуйте не про перевірку зведеності нанівець, а просто спосіб функціонального поводження з винятками.
Використання Спробуйте знайти виняток і перетворити його на Варіант для зручності не відображатиметься лише у випадку, якщо виняток трапиться.
scala> Try(1/0).toOption
res11: Option[Int] = None
Ви хочете зберегти цінності, що виходять із спробувати. Це може бути недійсним.
Але також правда, що стандартна ліб часом досить заплутана ...
scala> Try(null).toOption
res12: Option[Null] = Some(null)
scala> Option(null)
res13: Option[Null] = None
Така поведінка трохи непослідовна, проте вона відображає навмисне використання як Спробуйте, так і Варіант.
Ви використовуєте спробуйте отримати все, що виходить із виразу, який може кинути винятки, і вас не хвилює саме виняток.
Значення, яке може вийти, може бути нульовим. Якщо toOption дав None, ви не могли розмежувати виняток і null , і це не дуже!
Автономно, ви використовуєте Option, щоб інкапсулювати існування чи ні чогось. Так що в такому випадку Some (null) є None, і це має сенс, тому що null в цьому випадку являє собою відсутність чогось. Тут немає двозначності.
Важливо зауважити, що в будь-якому випадку прозорість референціалів не порушена, оскільки .toOption не збігається з Option ()
Якщо вам дійсно потрібно забезпечити БОЛЬНУ безпеку винятків І нульову безпеку, і ваш код дійсно не потребує розмежування між null та винятком , вам просто потрібно поєднувати обидві парадигми! Бо добре, це те, що ти хочеш, правда?
Ви можете це зробити одним способом ...
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)
... чи інший ...
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)
... або сміхотворніші з них чужі ...
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)