Scala类型在if语句中不匹配

时间:2019-11-03 15:19:29

标签: scala list tree

想知道为什么此代码不起作用,我是否遗漏了一些东西?

def treemin(lst: List[Any]): Int = {
  var MaVar: Int = 1000{
  case (sum,leaf: Int)  =>
    if(leaf < MaVar) {MaVar = leaf}
  }
}

我在这里出现错误:

if(leaf < MaVar) {MaVar = leaf}

错误:

  

错误:类型不匹配;找到:所需单位:整数

我已经看过here,但是由于我是scala的新手,所以未能解决这个问题,这可能是一个愚蠢的错误。

注意::这是获取树的最小叶子的好方法吗?

我有一棵树:

enter image description here

我正在尝试做一个将返回最小叶子的函数,例如,在这里它将返回2。

1 个答案:

答案 0 :(得分:0)

您的代码中实际上有两个 错误:

def treemin(lst: List[Any]): Int = {
  var MaVar: Int = 1000{
  case (sum,leaf: Int)  =>
    if(leaf < MaVar) {MaVar = leaf}
  }
}

第一个错误是这个:

         var MaVar: Int = 1000{
                              ^
On line 2: error: Int(1000) does not take parameters
       }
       ^

在这里,您正在尝试使用参数调用1000,就好像它是一个函数一样。目前尚不清楚您要在这里实现什么。您是否正在尝试创建新的词汇范围?然后,您需要添加一个空行,以便Scala不会将花括号解释为1000的参数:

def treemin(lst: List[Any]): Int = {
  var MaVar: Int = 1000

  {
    case (sum,leaf: Int)  =>
      if(leaf < MaVar) {MaVar = leaf}
  }
}

但是,现在又出现另一个错误,因为现在花括号被解释为创建匿名函数:

         {
         ^
On line 4: error: missing parameter type for expanded function
       The argument types of an anonymous function must be fully known. (SLS 8.5)
       Expected type was: Int

有多种方法可以解决此问题,但问题是:在这里创建新的词法范围是没有意义的,因为您没有在其中定义任何变量,因此没有什么可“作用域”的第一名。

摆脱它:

def treemin(lst: List[Any]): Int = {
  var MaVar: Int = 1000
  case (sum,leaf: Int)  =>
    if(leaf < MaVar) {MaVar = leaf}
}

现在,我们遇到另一个错误:

         case (sum,leaf: Int)  =>
         ^
On line 3: error: '}' expected but 'case' found.

从本质上告诉我们,case应该与match语句一起使用。由于我对您要匹配的内容还不太清楚,因此我无法再修复该代码。

这使我们进入第二个错误,它实际上非常简单:

       }
       ^
On line 6: error: type mismatch;
        found   : Unit
        required: Int

这指向方法的右花括号,它实际上表示您在方法定义中承诺该方法返回一个Int,但实际上您正在返回Unit。实际上,您根本没有明确返回任何东西。如果您未明确返回任何内容,则将返回在该方法内部求值的最后一个表达式的值。

在这种情况下,实际上很难理解所求值的最后一个表达式是什么,因为该方法存在错误,因此该方法将永远不会被求值。但是,让我们看一下两个候选人:

var MaVar: Int = 1000

这是一项作业。赋值的计算结果为Unit,因此,如果 this 是最后计算的表达式,则返回值确实为(),它是Unit的单例实例。 / p>

在该方法内部求值的最后一个表达式的另一个候选项是条件表达式:

if(leaf < MaVar) {MaVar = leaf}

现在,条件表达式的值是什么?嗯,这是采用任何分支的值,条件表达式的类型是两个分支的类型中最低的祖先。

条件表达式中的“ true”分支再次是一个赋值,正如我们在上文中所建立的,赋值的计算结果为()Unit

条件中的“假”分支不存在,但是如果被采用,则必须对其进行评估,因为在Scala中,一切都是表达式(没有语句),因此一切都求值为值。好吧,代表没有合理的返回值的值是()Unit。(您猜对了)。

因此,无论您如何看,它的方法总是返回Unit,而实际上却保证返回Int。这就是为什么出现类型错误。

您的方法还有其他一些奇怪之处:它接受一个参数,但从不使用它。并且,该参数的类型为List[Any],这是一个巨大的危险信号。 Scala具有非常强大的类型系统,几乎永远不会出现您不知道什么是特定类型的情况。 Any是最没用的类型,因为它不会告诉您任何类型以及它可以做什么。