简体   繁体   English

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

[英]Wrapping null-returning method in Java with Option in Scala?

Suppose I have a method session.get(str: String): String but you don't know whether it will return you a string or a null, because it comes from Java. 假设我有一个方法session.get(str: String): String但你不知道它是否会返回一个字符串或null,因为它来自Java。

Is there an easier way to treat this in Scala instead of session.get("foo") == null ? 有没有更简单的方法来处理Scala而不是session.get("foo") == null Maybe some magic apply like ToOption(session.get("foo")) and then I can treat it in Scala way like 也许一些魔术应用像ToOption(session.get("foo"))然后我可以像Scala一样对待它

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

The Option companion object's apply method serves as a conversion function from nullable references: Option伴随对象的apply方法用作来自可空引用的转换函数:

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

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

Option对象有一个apply方法,它正是这样做的:

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

Notice that when working with Java objects it won't work as expected: 请注意,使用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

This is a very old topic but a nice one! 这是一个非常古老的话题,但是很棒!

It's true that converting any Non-exception result of Try to Option will result in a Some... 确实,将Try的任何非异常结果转换为选项将导致一些......

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

...because Try is not about nullability checking but just a way to functionally handle exceptions. ...因为Try不是关于可空性检查,而只是一种功能上处理异常的方法。

Using Try to catch an exception and converting that to an Option for convenience will only show None in case an exception happens. 使用Try捕获异常并将其转换为Option以方便只在发生异常时才显示None。

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

You want to preserve the values that come out of Try. 您希望保留Try出来的值。 That may be null. 这可能是空的。

But it is also true that the standard lib is quite confusing sometimes... 但是标准的lib有时也很混乱......

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

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

This behaviour is a bit inconsistent but it kind of reflects the intented usage of both Try and Option. 这种行为有点不一致,但它反映了Try和Option的用法。

You use try to get whatever comes out of an expression that may throw exceptions, and you don't care about the exception itself. 您可以使用try来获取可能抛出异常的表达式,而您不关心异常本身。

The value that may come out may very well be a null. 可能出现的值很可能是null。 If toOption gave None, you could not differenciate between an exception and a null , and that is not pretty! 如果toOption给出None, 你就无法在异常和null之间进行区分 ,这不是很好!

Standalone, you use Option to encapsulate the existence or not of something. 独立,您使用Option来封装某些东西的存在与否。 So in that case Some(null) is None, and that makes sense, because null in that case represents the absence of something. 所以在那种情况下,Some(null)是None,这是有道理的,因为在这种情况下null表示没有东西。 There's no ambiguity here. 这里没有歧义。

It's important to remark that in any case referencial transparency is not broken since .toOption is not the same as Option() 此言在任何情况下的借鉴透明度不破,因为.toOption是一样的选择是很重要的()

If you really need to enforce BOTH exception safety AND null safety, and your code really really doesn't need to differenciate between null and an exception , you just need to combine both paradigms! 如果你真的需要强制执行BOTH异常安全 null安全,并且你的代码确实不需要在null和异常之间进行区分 ,那么你只需要结合两种范式! Because well, that's what you want, right? 好吧,那就是你想要的,对吧?

You can do it in one way... 你可以用一种方式做到......

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)

... or another ... ... 或其他 ...

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)

... or the ridiculously ugliest of them anothers ... ......或者其中最丑陋的人......

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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM