用Scala中的Option包装Java中的null返回方法?


107

假设我有一个方法,session.get(str: String): String但是您不知道它会返回字符串还是null,因为它来自Java。

在Scala中,有没有更简单的方法来解决此问题session.get("foo") == null?也许有些魔术适用ToOption(session.get("foo")),然后我可以像这样在Scala中对待它

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

4
有关更多选择技巧,请参阅blog.tmorris.net/scalaoption-cheat-sheet
Landei 2011年

Answers:


182

Option同伴对象的apply方法作为从可空引用转换函数:

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

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

19

Option对象具有一种apply完全可以做到这一点的方法:

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

5

请注意,使用Java对象时,它将无法按预期工作:

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。第二行抛出NullPointerException。第六行得到Some(null),而不是您所期望的None。
约翰·林

1.在OptionString中使用Some代替Option-原始答案已更改。2.仅在Scala 2.12.5
DekelM中

-3

这是一个非常古老的话题,但却是一个不错的话题!

的确,将任何非例外的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)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.