这是一个非常古老的话题,但却是一个不错的话题!
的确,将任何非例外的Try转换为Option都会导致Some ...
scala> Try(null).toOption
res10: Option[Null] = Some(null)
...因为尝试不是关于可空性检查,而仅仅是功能上处理异常的一种方法。
为方便起见,使用“尝试捕获”异常并将其转换为Option只会在发生异常的情况下显示“无”。
scala> Try(1/0).toOption
res11: Option[Int] = None
您想保留来自Try的值。可能为空。
但是标准lib有时确实很令人困惑...
scala> Try(null).toOption
res12: Option[Null] = Some(null)
scala> Option(null)
res13: Option[Null] = None
这种行为有点不一致,但是它反映了Try和Option的预期用法。
您可以使用try来获取表达式中可能引发异常的任何内容,而无需关心异常本身。
可能出现的值很可能为空。如果toOption给出None,则无法区分异常和null,那不是很漂亮!
独立地,您可以使用Option封装某些事物的存在与否。因此,在这种情况下,Some(null)为None,这是有道理的,因为在这种情况下,null表示缺少某些东西。这里没有歧义。
此言在任何情况下的借鉴透明度不破,因为.toOption是很重要的不一样的选项()
如果你真的需要强制执行BOTH异常安全和空安全,以及你的代码真的不需要空和异常之间differenciate,你只需要两种范例结合!因为好吧,这就是您想要的,对吗?
您可以用一种方式来做...
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)