【问题标题】:Nested function skews return type of its parent嵌套函数倾斜其父级的返回类型
【发布时间】:2017-06-18 04:42:39
【问题描述】:

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

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。这不太有意义,因为一旦解决了原始 case 括号,返回 true 或 false,它应该到方法的末尾,并且完成,对吗?解决方法是什么?

【问题讨论】:

  • 提示:方法的返回值是方法中计算的最后一个表达式的值。提示 #2:方法中评估的最后一个表达式是什么?提示 #3:函数定义的价值是什么?

标签: scala pattern-matching case


【解决方案1】:

发生这种情况是因为您的方法是作用域中的最后一个声明,这使得编译器发出 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 来解决此问题。我会坚持重新排序的方法。

【讨论】:

  • 啊哈,谢谢。我曾尝试将 var b: boolean = false 设置为isTriangular 的第一行,然后将n match 的第二行设置为:case _ =&gt; b == triangularMaths(n, 1) ,然后在整个结束括号之前返回b,但是如果它被评估为 true,它不会记住对 b 的更改。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-10
  • 1970-01-01
  • 2013-08-13
  • 2010-10-01
相关资源
最近更新 更多