为什么我会遇到类型不匹配错误?

时间:2016-05-02 10:21:36

标签: scala generics type-mismatch

我无法理解为什么以下代码会出现类型不匹配错误 - 在这里,我使用泛型,在第11行,它给出了类型不匹配错误。不应该将T解释为Int。

object FunctionParamGeneric {
  def main(args: Array[String]) : Unit= {
    exec[Int](Fun[Int])
  }

  def exec[T]( f:() => T) : T = {
    println("Inside exec")
    f()
  }

  def Fun[T]() : T = {
    println("Inside Fun with key ")
    123
  }
}

然而,如果我这样做

object FunctionParamGeneric {
   def main (args: Array[String]) : Unit= {
     exec[Int](() => 1)
   }

   def exec[T]( f:() => T) : T = {
     println("Inside exec")
     f()
   }

 }

工作正常。因为推断f在第二个代码段中使用Int进行调用,我希望在第一个代码段中也会发生同样的情况,但事实并非如此。为什么不呢?

2 个答案:

答案 0 :(得分:3)

第一个片段:

您收到错误,因为您在返回Fun时已为Int指定了通用返回类型。

假设如果允许这个表达式,现在考虑这两个语句:

Fun[Int]()    // would have returned 123

Fun[String]() // what would be output?

第一个语句会返回123没有任何问题,但第二种情况下的输出是什么?

这就是为什么不允许这样的表达。

第二段:

在第二个代码段中,它可以正常运行,因为当您使用exec[Int](() => 1)时,您将传递一个文字函数作为参数,而在第一个代码段中您给出了Fun的定义。

如果你看一下exec

的定义,进一步解释一下
def exec[T]( f:() => T) : T

它需要一个Function0函数(可以返回任何类型)作为参数。因此,当您调用exec[Int](() => 1)时,您正在传递函数() => 1,它返回Int注意这不是通用函数)。因此它有效。

在第一个片段中,您定义了具有泛型返回类型的泛型函数Fun。但是从函数体中返回Int值。

答案 1 :(得分:1)

你的问题在于:

def Fun[T]() : T = {
  println("Inside Fun with key ")
  123
}

您隐含地返回123。哪个不是T类型,而是Int类型。因此编译器会生成错误。

如果您希望Fun始终返回Int,则可以将其定义为Fun(): Int = ...

然后你应该可以打电话了

exec[Int](Fun)