我正在编写一个函数并遇到一个奇怪的问题。我使用了模式匹配,然后是一个内部函数,它使用了一个稍微改变但几乎相同的模式,并且它不是在编译:
def isTriangular(n: Int): Boolean = {
n match {
case n if n < 1 => false
case _ => triangularMaths(n, 1)
}
def triangularMaths(j:Int, counter: Int): Boolean = (j, counter) match {
case _ if j-counter == 0 => true
case _ if j-counter < 0 => false
case _ => triangularMaths(j-counter, counter+1)
}
}
对此的修复是我简单地将它们设为两个单独的方法,只要triangularMaths
没有嵌套,它们就可以工作。但是,由于triangularMaths
仅针对triangular
,因此我希望它能够嵌套。但是,当我这样做时,我的编译器抱怨,告诉我我正在返回Unit
,而不是预期的Boolean
。这没有多大意义,因为一旦解决了原始案例括号,返回true或false,它应该到达方法的末尾,并完成,正确吗?解决了什么?
答案 0 :(得分:3)
这是因为您的方法是作用域中的最后一个声明,这使得编译器将Unit
值作为返回类型发出。反编译代码如下所示:
def main(args: Array[String]): Unit = {
def isTriangular(n: Int): Boolean = {
n match {
case (n @ _) if n.<(1) => false
case _ => triangularMaths(n, 1)
};
def triangularMaths(j: Int, counter: Int): Boolean = scala.Tuple2.apply[Int, Int](j, counter) match {
case _ if j.-(counter).==(0) => true
case _ if j.-(counter).<(0) => false
case _ => triangularMaths(j.-(counter), counter.+(1))
};
()
};
首先定义triangularMaths
,然后调用它:
def isTriangular(n: Int): Boolean = {
def triangularMaths(j: Int, counter: Int): Boolean = (j, counter) match {
case _ if j - counter == 0 => true
case _ if j - counter < 0 => false
case _ => triangularMaths(j - counter, counter + 1)
}
n match {
case n if n < 1 => false
case _ => triangularMaths(n, 1)
}
}
另一种可能性是将模式匹配分配给值,然后将该值作为方法的最后一个表达式返回。但是,这会使编译器抱怨前向引用,您可以通过将其改为lazy val
来修复。我会坚持重新订购的方法。