Scala泛型类型不匹配

时间:2015-10-29 13:51:42

标签: scala generics

在Scala中,我正在尝试:

import scala.reflect.runtime.{universe => ru}
def foo[T <: Any]: ru.WeakTypeTag[T] = ru.weakTypeTag[String]

但是这让我产生了:

<console>:34: error: type mismatch;
 found   : reflect.runtime.universe.WeakTypeTag[String]
 required: reflect.runtime.universe.WeakTypeTag[T]
 def foo[T <: Any]: ru.WeakTypeTag[T] = ru.weakTypeTag[String]

这里有什么?我相对确定String应该满足从T派生的Any类型约束...

我猜String无法绑定到T类型参数。在我的用例中,也可以返回其他类型,但我不确定如何在执行函数之前预先得到编译器的答案,如果这是它所期望的。

2 个答案:

答案 0 :(得分:6)

您的方法foo声称,对于任何T <: Any,它都会返回WeakTypeTag[T]。也就是说,如果T是(例如)Int,则应返回WeakTypeTag[Int]。但是,您的方法始终返回WeakTypeTag[String],因此类型不匹配。

答案 1 :(得分:1)

作为替代方案,您可以使用通配符,无论如何您的类型都是从Any扩展。

def foo[T <: Any]: ru.WeakTypeTag[_] = ru.weakTypeTag[String]

一般来说,问题在于WeakTypeTag [T]类的定义。它是不变的。所以你不能在协变的情况下使用它。

我们来看一个例子。

  def bom[T >: String]: List[T] = List[String]() // works fine
  def foo[T >: String]: WeakTypeTag[T] = ru.weakTypeTag[String] // compilation fails

我将T定义为String的任何子类型,它适用于Lists,但对于WeakTypeTag不可用。 您可以定义WeakTypeTag的子类型并使其协变,以便完美起作用。

  trait WeakTypeTag1[+X] extends ru.WeakTypeTag {
  }

  def weakTypeTag1[T](implicit attag: WeakTypeTag1[T]) = attag

  def foo[T >: String]: WeakTypeTag1[T] = weakTypeTag1[String] // no it's good