如何将可以为null或数组的值隐式包装到Scala选项中 [英] How to implicitly wrap a value that can be null or an array into an Scala Option
问题描述
我在Jar文件中包含这个Java类,作为Scala程序的依赖项(例如Axis jar):
I have this Java class in a Jar file included as a dependency of an Scala program (like the Axis jar):
class MyClass {
private String[] someStrings;
public String[] getSomeStrings() { return someStrings; }
}
在我的Scala程序中,我有一个Java API,可以将MyClass的MyClass实例的实例返回到我在Scala中的程序:
In my Scala program I have a Java API that return an instance of MyClass instance of MyClass to my program in Scala:
val myInstance = JavaAPI.getInstanceOfMyClass()
然后,我尝试在我的Scala程序中使用 someStrings 数组,但是它为 null (假设它没有正确初始化)
Then I try to use the someStrings array in my Scala program but it's null (let say that it wasn't properly initialized)
for(str <- myInstance.getSomeStrings()) ...
因此,这将引发 NullPointerException .
我发现为了在理解中使用它,我可以将其包装到Option中,以便其正确处理NPE.
I've found that in order to use it in the for comprehension I can wrap it into an Option so that it handles the NPE properly.
for(str <- Option[Array[String]](myInstance.getSomeStrings).getOrElse(Array[String]())
但是,对我来说,这看起来并不好.
But that doesn't look OK to me.
有没有一种创建类似隐式方法的方法,即使该方法为空也可以将该值包装到Option中,例如:
Is there a way to create like an implicit method that takes that value even if it's null and wrap it into the Option, like:
implicit def wrapNull(a: Null): Option[Nothing] = None
implicit def wrapArray(a: Array[String]): Option[Array[String]] = Some(a)
所以当我这样做:
for(str <- myInstance.getSomeStrings())
我没有获得 NPE
提前谢谢!
推荐答案
我认为您使用getOrElse
的版本没有那么糟糕(您可以通过在Option
之后删除[Array[String]]
来使其更短一些,因为可以推断出这一点).如果您想要更简洁的方法,可以使用以下方法:
I don't think your version with getOrElse
is that bad (you can make it a little shorter by removing the [Array[String]]
after Option
, since that can be inferred). If you want something even more concise, the following works:
for (str <- Option(myInstance.getSomeStrings).flatten) ...
您还可以使用Option
具有foreach
的事实:
You could also use the fact that Option
has a foreach
:
for {
strings <- Option(myInstance.getSomeStrings)
str <- strings
} ...
请注意,此处不能使用yield
,原因是drexin在下面的注释中突出显示.
Note that you can't use yield
here, for the reason that drexin highlights in a comment below.
或者您可以皮条客 MyClass
:
implicit def withNullWrapper(c: MyClass) = new {
def getSomeStringsOrNot() = Option(c.getSomeStrings).getOrElse(Array[String]())
}
for (str <- myInstance.getSomeStringsOrNot) ...
这篇关于如何将可以为null或数组的值隐式包装到Scala选项中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!