【问题标题】:When to use keyword return in Scala何时在 Scala 中使用关键字 return
【发布时间】:2021-04-04 04:30:42
【问题描述】:

我很早就知道没有理由在 Scala 中使用 return 关键字(据我所知)。话虽如此,我找到了一个示例,其中只需更改添加 return 关键字即可使我的函数正常工作,而以前却不能。

有问题的代码来自 my solutionAdvent of Code 第 7 天的挑战。


def containsShinyGoldBag(bagContents: Map[String, List[String]], currentBag: String): Boolean = {
    val contents = bagContents(currentBag)

    if (bagContents(currentBag).contains("shiny gold") ) {
        // Base Case: Bag Found in list of bags
        true
    } else if (contents == List.empty){
        // Base Case: Dead End
        false
    } else {
        // Continue searching down list

        // Ideal solution ( gives same result as the working solution without return keyword )
        // for (b <- contents) containsShinyGoldBag(bagContents, b)

        // Working solution
        for (b <- contents) {
            if (containsShinyGoldBag(bagContents, b)) {
                println(s"Found one! $b inside a $currentBag")
                return true // <--- culprit
            }
            else false
        }
        false
    }
}

// In the main function

var count = 0
for (bag <- bagContents.keys) {
    if (containsShinyGoldBag(bagContents, bag)) {
        count = count + 1
    }
}
println(s"There are $count way to bring a shiny gold bag!")

当我在没有return 的情况下运行代码时,我最终得到count = 7,这是直接包含闪亮金袋的袋子的数量,而不是计算内部某处包含闪亮金袋的袋子的正确数字他们的其他包之一。

【问题讨论】:

  • 从技术上讲,您永远不需要它,每个可能需要它的算法都可以以某种不需要它的方式重写。 - 实际上,有时替代方案更难理解或效率更低,那么为什么不使用它呢? - 就个人而言,我从来没有找到使用它的充分理由(在我自己的代码中),因为它通常在更命令式的代码中很常见,而我的通常更实用,比如 cats 仅使用 stdlib traverse 是最常见的示例) 为您可能需要它提供很好的替代方案。
  • @LuisMiguelMejíaSuárez 我知道没有必要。我只是问这个具体的例子如何使添加return 得到不同的结果
  • 是的,这正是避免它的原因。因为它可能意味着不同的东西。有时它可能意味着你想要它的意思(像这种情况)有时它不是。
  • return 的问题在于它并不总是像 return 在 Java 中那样工作 - 非本地返回(来自 lambdas 和 for 循环)使用异常来突破而且很乱。

标签: scala recursion return sbt


【解决方案1】:

函数返回它计算的最后一个表达式的值;在您的情况下,这将是以下之一:

  1. trueif (bagContents(currentBag).contains("shiny gold") ) 之后;

  2. falseelse if (contents == List.empty) 之后;

  3. 最后一个false

true 不在这样的位置,所以你需要return 来让函数返回它。否则,它会被评估并忽略,因为您不使用它做任何事情。 else false也是同一个for,其实可以去掉而不改变意思。

这里避免return的替代方法是

contents.exists(b => containsShinyGoldBag(bagContents, b))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-22
    • 2014-12-24
    • 2016-03-11
    • 2015-04-23
    相关资源
    最近更新 更多