如何将可以为 null 的值或数组隐式包装到 Scala 选项中

2024-04-19

我在 Jar 文件中包含这个 Java 类,作为 Scala 程序的依赖项(如 Axis jar):

class MyClass {
    private String[] someStrings;
    public String[] getSomeStrings() { return someStrings; }
}

在我的 Scala 程序中,我有一个 Java API,它将 MyClass 的实例返回到我在 Scala 中的程序:

val myInstance = JavaAPI.getInstanceOfMyClass()

然后我尝试使用一些字符串我的 Scala 程序中的数组,但它是null(假设它没有正确初始化)

for(str <- myInstance.getSomeStrings()) ...

所以这会抛出一个空指针异常.

我发现为了在 for 理解中使用它,我可以将它包装到一个 Option 中,以便它正确处理 NPE。

for(str <- Option[Array[String]](myInstance.getSomeStrings).getOrElse(Array[String]())

但这对我来说看起来不太好。

有没有一种方法可以创建像隐式方法一样的方法,即使该值为空,也可以将其包装到选项中,例如:

implicit def wrapNull(a: Null): Option[Nothing] = None
implicit def wrapArray(a: Array[String]): Option[Array[String]] = Some(a)

所以当我这样做时:

for(str <- myInstance.getSomeStrings())

我不明白NPE


edit:

A map以及ASAflatMap始终必须返回调用它们的相同类型。如果你有一个列表,你总是会从map。期权也是如此。如果您尝试在 flatMap 中混合两种类型,这很可能行不通。什么应该

Some(Array(1,2)).flatMap { x => 
  x.map { _ * 2 }
}

返回? Some(2,4) 是不可能的。所以你会得到一个类型错误。由于这个原因,你必须做一个嵌套map { map }代替flatMap { map }.

在你的情况下,它会像这样工作:

case class A(b: B)
case class B(c: String)

val result = for(as <- Option(Array(A(B("foo")), A(B("bar"))))) yield {
  for(a <- as; b <- Option(a.b); c <- Option(b.c)) yield {
    c
  }
}

首先for需要一个Option[Array[A]]并返回一个Option[Array[String]]。嵌套的 for 需要一个Array[A]并返回一个Array[String]。它们都满足单子定律。最后您可以安全地拨打电话getOrElse on result如果需要的话,可以解开该值。

原来的:

你可以这样做

val result = Option(myInstance.getSomeStrings).map { x =>
  x.map { y =>
    // do stuff with strings
  }
}

or

val result = for(x <- Option(myInstance.getSomeStrings)) yield {
  x.map { y =>
    // do stuff with strings
  }
}

由于类型推断,您不需要编写类型,并且不需要getOrElse,因为地图不会被执行None。然后你可以简单地做一个getOrElse在结果上,如果您需要解开该值。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何将可以为 null 的值或数组隐式包装到 Scala 选项中 的相关文章

随机推荐