嵌套函数倾斜返回其父级的类型

时间:2017-02-01 12:21:57

标签: scala pattern-matching case

我正在编写一个函数并遇到一个奇怪的问题。我使用了模式匹配,然后是一个内部函数,它使用了一个稍微改变但几乎相同的模式,并且它不是在编译:

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,它应该到达方法的末尾,并完成,正确吗?解决了什么?

1 个答案:

答案 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来修复。我会坚持重新订购的方法。