在Scala代码中键入不匹配错误

时间:2018-01-06 17:42:02

标签: scala

我正在尝试解决项目Euler,问题5.我在互联网上找到了很多解决方案,但我正在尝试自己的版本(不是那么功能性的方法)。我遇到了错误:type mismatch found :Unit Required:Boolean

object Euler5 {

  def divby1to10(input: Int): Boolean = {
    for (i <- 1 to 10) { // type mismatch found :Unit Required:Boolean
      if (input % i == 0)
        false
      else true
    }
  }

  def main(args: Array[String]): Unit = {
    println(divby1to10(5))
  }
}

如果删除:Boolean,代码会编译,但输出为()。有人可以帮我弄清楚这段代码有什么问题并给我一个解决方案吗?

3 个答案:

答案 0 :(得分:1)

考虑一下for循环正在做什么。

for (i <- 1 to 10) {
  if (input % i == 0)
    false
  else true
}

您循环十次并产生十种不同的结果。现在,我想你希望这些falsetrue值向外传播,但如果某些迭代步骤返回false和其他true会怎样?您还没有指定您希望它们的组合方式。因此,在Scala中,(命令式)for循环始终返回()。我想你想要的是

for (i <- 1 to 10) {
  if (input % i != 0)
    return false // Definitely doesn't divide them all, so return false now
  // If it does divide, continue the loop
}
// If we get to this point, it divided them all, so return true
true

答案 1 :(得分:1)

问题是,您的for循环的返回类型为Unit,而在您的函数定义中,您需要Boolean

表达逻辑的更实用的方法可能是:

def divby1to10(input: Int): Boolean = (1 to 10).forall(input % _ == 0)

答案 2 :(得分:0)

在Scala中,与其他编程语言不同,例如Java控制流构造如 if for while 是返回某种类型值的表达式。

在给定的具体示例中, for 语句返回单位,因为Scala language specification中的以下语句指出:

  

(p&lt; -e)e'的for循环被转换为e.foreach {case p =&gt; e'}

在您的示例中,e的类型为范围(更具体地说是Range.Inclusive)。 对于该类型,定义 foreach 以便它返回Unit。因此,您的整个表达式会产生单位。最后,因为 for 表达式是函数的最后一个语句,函数本身也返回Unit,因此错误。

通常,foreach构造而不是返回某些值用于对每个生成的值 p 产生副作用,例如打印到控制台,因此返回类型单位。因此,对于您的特定任务,它可能不适合。正如在其他答案中所解释的那样,有几种方法可以重写逻辑,以便函数返回布尔值。