简体   繁体   English

Scala泛型类型不匹配

[英]Scala generics type mismatch

In Scala, I'm trying: 在Scala中,我正在尝试:

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

But this yields me: 但这产生了我:

<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]

What's up here? 怎么了 I'm relatively sure String should satisfy T 's type constraint of deriving from Any ... 我相对确定String应该满足T的派生自Any的类型约束。

I guess String failed to bind to the T type parameter. 我猜想String无法绑定到T类型参数。 In my use case other types may be returned as well though, and I'm not sure how I could get that answer to the compiler up-front before executing the function, if that's what it's expecting. 在我的用例中,也可能会返回其他类型,而且我不确定在执行该函数之前,如何预先获得编译器的答案,如果这是预期的话。

Your method foo claims that, for any T <: Any , it returns a WeakTypeTag[T] . 您的方法foo声明,对于任何T <: Any ,它将返回WeakTypeTag[T] That is, if T is (for instance) Int , it should return a WeakTypeTag[Int] . 也就是说,如果T是(例如) Int ,则它应返回WeakTypeTag[Int] However, your method always returns a WeakTypeTag[String] , hence the type mistmatch. 但是,您的方法总是返回WeakTypeTag[String] ,因此类型为mistmatch。

As an alternative you can use wildcard, anyway your type is extended from Any. 作为替代方案,您可以使用通配符,无论如何您的类型都是从Any扩展的。

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

In general the problem is with definition of WeakTypeTag[T] class. 通常,问题在于WeakTypeTag [T]类的定义。 It is defined invariantly. 它是不变定义的。 So you can not use it in covariant case. 因此,您不能在协变情况下使用它。

Let's go with an examples. 让我们来看一个例子。

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

I'm defining T as any subtype of String and it works good for Lists but fails for WeakTypeTag that is invariant. 我将T定义为String的任何子类型,它适用于ListsWeakTypeTag用于不变的WeakTypeTag You can define sub type of WeakTypeTag and make it covariant so it will perfectly works. 您可以定义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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM