gpt4 book ai didi

scala - 重复函数调用,直到我们在 Scala 中得到非空的 Option 结果

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

Scala 中的一个非常新手的问题 - 我如何在 Scala 中执行“重复函数直到返回的内容符合我的条件”?

鉴于我有一个我想调用的函数,直到它返回结果,例如,定义如下:

def tryToGetResult: Option[MysteriousResult]

想出了这个解决方案,但我真的觉得它很难看:
var res: Option[MysteriousResult] = None
do {
res = tryToGetResult
} while (res.isEmpty)
doSomethingWith(res.get)

或者,同样丑陋:
var res: Option[MysteriousResult] = None
while (res.isEmpty) {
res = tryToGetResult
}
doSomethingWith(res.get)

我真的觉得有一个没有 var 的解决方案并且没有那么多手动检查是否 Option 的麻烦是否为空。

相比之下,我看到的 Java 替代品在这里似乎更清晰:
MysteriousResult tryToGetResult(); // returns null if no result yet

MysteriousResult res;
while ((res = tryToGetResult()) == null);
doSomethingWith(res);

雪上加霜,如果我们不需要 doSomethingWith(res)我们只需要从这个函数返回它,Scala vs Java 看起来像这样:

斯卡拉
def getResult: MysteriousResult = {
var res: Option[MysteriousResult] = None
do {
res = tryToGetResult
} while (res.isEmpty)
res.get
}

java
MysteriousResult getResult() {
while (true) {
MysteriousResult res = tryToGetResult();
if (res != null) return res;
}
}

最佳答案

您可以使用 Streamcontinually方法来做到这一点:

val res = Stream.continually(tryToGetResult).flatMap(_.toStream).head

或者(可能更清楚):
val res = Stream.continually(tryToGetResult).dropWhile(!_.isDefined).head

这种方法优于显式递归(除了简洁)的一个优点是它更容易修补。例如,假设我们决定只想尝试获得一千次结果。如果一个值在那之前出现,我们希望它包含在 Some 中。 ,如果不是我们想要一个 None .我们只需在上面的代码中添加几个字符:
Stream.continually(tryToGetResult).take(1000).flatMap(_.toStream).headOption

我们有我们想要的。 (请注意, Stream 是惰性的,所以即使 take(1000) 存在,如果在三次调用 tryToGetResult 后值出现,它只会被调用三次。)

关于scala - 重复函数调用,直到我们在 Scala 中得到非空的 Option 结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13504461/

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