gpt4 book ai didi

java - 如何在 scala 中重写此 java 函数并保持相同的可选输入参数?

转载 作者:行者123 更新时间:2023-12-02 09:08:10 24 4
gpt4 key购买 nike

我在java中有以下方法

protected <T> T getObjectFromNullableOptional(final Optional<T> opt) {
return Optional.ofNullable(opt).flatMap(innerOptional -> innerOptional).orElse(null);
}

需要一个java Optional它本身可以是 null (我知道,这真的很糟糕,我们最终会解决这个问题)。它用另一个 Optional 包裹它所以它变成 Some(Optional<T>)None 。然后是flatMapped ,所以我们返回Optional<T>None ,最后申请orElse()获取Tnull .

如何在 scala 中使用相同的 java.util.Optional 编写相同的方法?

protected def getObjectFromNullableOptional[T >: Null](opt : Optional[T]): T =
???

我试过了

protected def getObjectFromNullableOptional[T >: Null](opt : Optional[T]): T =
Optional.ofNullable(opt).flatMap(o => o).orElse(null)

但这给了我一个Type mismatch错误

Required: Function[_ >: Optional[T], Optional[NotInferedU]]

Found: Nothing => Nothing

我试过了

protected def getObjectFromNullableOptional[T >: Null](opt : Optional[T]): T =
Option(opt).flatMap(o => o).getOrElse(null)

但这给了我

Cannot resolve overloaded method 'flatMap'

编辑 我忘记提及我正在使用 scala 2.11。我相信 @tefanobaghino 的解决方案适用于 scala 2.13,但它引导我走向正确的道路。我把我的最终解决方案放在这个解决方案下的评论中

最佳答案

最后一个错误引起了一些怀疑:看起来您正在将 Java Optional 包装在 Scala Option 中。相反,我本来预计这会失败,因为您试图将 flatMap 转换为不同的类型,例如

error: type mismatch;
found : java.util.Optional[T] => java.util.Optional[T]
required: java.util.Optional[T] => Option[?]

这似乎满足您的要求:

import java.util.Optional

def getObjectFromNullableOptional[T](opt: Optional[T]): T =
Optional.ofNullable(opt).orElse(Optional.empty).orElse(null.asInstanceOf[T])

assert(getObjectFromNullableOptional(null) == null)
assert(getObjectFromNullableOptional(Optional.empty) == null)
assert(getObjectFromNullableOptional(Optional.of(1)) == 1)

你可以试试这个 here on Scastie .

请注意,asInstanceOf 被编译为强制转换,而不是实际的方法调用,因此此代码不会抛出 NullPointerException

您还可以通过稍微帮助 Scala 的类型推断来研究更接近原始解决方案的内容:

def getObjectFromNullableOptional[T](opt: Optional[T]): T =
Optional.ofNullable(opt).flatMap((o: Optional[T]) => o).orElse(null.asInstanceOf[T])

或者使用 Scala 的identity:

def getObjectFromNullableOptional[T](opt: Optional[T]): T =
Optional.ofNullable(opt).flatMap(identity[Optional[T]]).orElse(null.asInstanceOf[T])

对于使用 Scala 的 Option 的解决方案,您可以做一些非常接近的事情:

def getObjectFromNullableOption[T](opt: Option[T]): T =
Option(opt).getOrElse(None).getOrElse(null.asInstanceOf[T])

请注意,使用 Scala 的 Option 转到您的 flatMap 解决方案可以让您避免必须明确函数类型:

def getObjectFromNullableOption[T](opt: Option[T]): T =
Option(opt).flatMap(identity).getOrElse(null.asInstanceOf[T])

我不完全确定具体细节,但我相信问题是,当使用 java.util.Optional 时,您将 Scala Function 传递给 Optional.flatMap,它采用 Java Function。 Scala 编译器可以自动为您转换它,但显然您必须具体且明确地了解类型才能使其工作,至少在本例中是这样。

关于原始代码的注释:您要求 T 成为 Null 的父类(super class)型,但这不是必需的。

您对自己正在做的事情有更好的背景,但作为一般建议,通常最好尽可能避免 Scala 代码中出现 null 泄漏。

关于java - 如何在 scala 中重写此 java 函数并保持相同的可选输入参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59634045/

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