【问题标题】:Scala generics type mismatchScala 泛型类型不匹配
【发布时间】:2015-10-29 23:16:56
【问题描述】:

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

【问题讨论】:

  • 定义返回类型时可以使用通配符:def foo[T &lt;: Any]: ru.WeakTypeTag[_] = ru.weakTypeTag[String]
  • 哈,太棒了,谢谢。您介意将其发布为答案吗? :)

标签: scala generics


【解决方案1】:

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

【讨论】:

  • 谢谢。我可以让它允许我返回我想要的东西吗?我的实际方法是递归的,迫使我明确返回类型,而在执行之前它不知道返回类型标记的确切内容......
  • @Tycho 如果你不分享实际代码,就很难帮助你做你真正想做的事。
【解决方案2】:

作为替代方案,您可以使用通配符,无论如何您的类型是从 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-12-21
    • 1970-01-01
    • 2015-04-09
    • 1970-01-01
    • 2016-10-21
    • 1970-01-01
    • 2013-07-06
    • 2014-10-30
    相关资源
    最近更新 更多