用Scala中的Option包装Java中的空返回方法?
Posted
技术标签:
【中文标题】用Scala中的Option包装Java中的空返回方法?【英文标题】:Wrapping null-returning method in Java with Option in Scala? 【发布时间】:2011-06-09 05:09:48 【问题描述】:假设我有一个方法session.get(str: String): String
,但你不知道它会返回一个字符串还是一个空值,因为它来自Java。
在 Scala 中是否有更简单的方法来处理这个问题而不是 session.get("foo") == null
?也许像ToOption(session.get("foo"))
这样应用了一些魔法,然后我可以像
ToOption(session.get("foo")) match
case Some(_) =>;
case None =>;
【问题讨论】:
更多Option技巧见blog.tmorris.net/scalaoption-cheat-sheet 上面的链接应该是blog.tmorris.net/posts/scalaoption-cheat-sheet。 【参考方案1】:Option
伴随对象的 apply
方法用作可空引用的转换函数:
scala> Option(null)
res4: Option[Null] = None
scala> Option(3)
res5: Option[Int] = Some(3)
【讨论】:
【参考方案2】:Option
对象有一个 apply
方法可以做到这一点:
var myOptionalString = Option(session.get("foo"));
【讨论】:
【参考方案3】:请注意,使用 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
【讨论】:
我使用 scala 2.11.8 运行。第二行抛出 NullPointerException。第六行得到 Some(null),而不是你预期的 None。 1.在 optionString 中使用 Some 而不是 Option - 更改了原始答案。 2. 仅在 Scala 2.12.5 中验证【参考方案4】:这是一个非常古老的话题,但很好!
确实,将 Try 的任何 Non-exception 结果转换为 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,这并不漂亮!
Standalone,你使用 Option 来封装某物的存在与否。所以在那种情况下 Some(null) 是 None,这是有道理的,因为在这种情况下 null 表示缺少某些东西。这里没有歧义。
重要的是要注意,在任何情况下都不会破坏参考透明度,因为 .toOption 不与 Option() 相同
如果您确实需要执行 BOTH 异常安全AND 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)
【讨论】:
以上是关于用Scala中的Option包装Java中的空返回方法?的主要内容,如果未能解决你的问题,请参考以下文章