117

假设我有一个方法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

4 回答 4

202

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

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

scala> Option(3)   
res5: Option[Int] = Some(3)
于 2011-01-14T15:22:57.547 回答
20

Option对象有一个apply方法可以做到这一点:

var myOptionalString = Option(session.get("foo"));
于 2011-01-14T15:23:39.280 回答
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
于 2018-06-12T06:42:44.047 回答
-2

这是一个非常古老的话题,但很好!

确实,将 Try 的任何非异常结果转换为 Option 都会导致 Some...

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

...因为 Try 不是关于可空性检查,而只是一种在功能上处理异常的方法。

使用 Try 捕获异常并将其转换为 Option 以方便仅在发生异常时显示 None 。

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

您想保留 Try 产生的值。那可能是空的。

但标准库有时也很令人困惑,这也是事实......

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与 Option() 不同

如果您真的需要同时执行异常安全null 安全,并且您的代码真的不需要区分 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)
于 2019-09-06T13:22:34.873 回答