gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-01 09:04:44 25 4
gpt4 key购买 nike

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

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

在我的 Scala 程序中,我有一个 Java API,它将 MyClass 的 MyClass 实例返回给我在 Scala 中的程序:
val myInstance = JavaAPI.getInstanceOfMyClass()

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

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

我发现为了在 for comprehension 中使用它,我可以将它包装到一个 Option 中,以便它正确处理 NPE。
for(str <- Option[Array[String]](myInstance.getSomeStrings).getOrElse(Array[String]())

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

有没有一种方法可以像隐式方法一样创建即使它为 null 并将其包装到 Option 中的隐式方法,例如:
implicit def wrapNull(a: Null): Option[Nothing] = None
implicit def wrapArray(a: Array[String]): Option[Array[String]] = Some(a)

所以当我这样做时:
for(str <- myInstance.getSomeStrings())

我没有收到 NPE

提前致谢!

最佳答案

编辑:

一个 map以及 flatMap总是必须返回相同的类型,它们被调用。如果你有一个列表,你总是会从 map 得到一个列表。 .对于一个选项也是如此。如果您尝试在 flatMap 中混合 2 种类型,这很可能不起作用。什么应该

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] .它们都满足单子(monad)定律。最后您可以放心调用 getOrElseresult如果您愿意,可以打开该值。

原来的:

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

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

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

关于scala - 如何将可以为 null 或数组的值隐式包装到 Scala 选项中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10131873/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com