在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
类型参数。在我的用例中,也可以返回其他类型,但我不确定如何在执行函数之前预先得到编译器的答案,如果这是它所期望的。
答案 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