微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

对于泛型类型和它的类型参数的Scala类型推断 – 为什么它不起作用?

如果我要说出关于 scala的最令人烦恼的事情,那么对于以下代码

trait G[+T]
class H[+T] extends G[T]

def f[A<:G[X],X<:Int](g :A)

val g :H[Int]
f(g)

编译器推断最后一次调用f [H [Int],nothing]的类型,并在我面前因为自己的愚蠢而抱怨.

然而,知道scala,它实际上比我更清楚.它背后的原因是什么?由于G和H在T方面都是协变的,因此S <:G [X]与H [_] =>.对于任何类型S,S<:H [X].这个缺点使我设计了一切,避免必须明确指定类型 - 这里看起来没什么,但是当名称变成'真实'长度时,几乎任何方法都是通用,并且经常处理两种泛型类型,事实证明大多数代码都是类型声明. 编辑:
上面的案例在下面由Noah解决,但是当派生类与基类不同时,如下所示?

trait G[+X]
class H[+X,Y] extends G[X]
class F extends G[Int]
def f[A<:G[X],X<:Int](g :A) = g

val h: H[Int,String] = ???
val g :F = ???
f(g)
f(h)

解决方法

如果你让A取一个类型参数A [_]我认为你可以让Scala编译器同意你,而不是只做一切:

def f[A[_] <: G[_],X <: Int](g: A[X])

作为旁注,我通常会在遇到类型问题时查看scalaz代码,因为它们通常会遇到它并尽可能地解决它.

UPDATE

我上面提供的方法仍然适用于给出的附加约束:

trait G[+X]

  class H[+X,Y] extends G[X]

  class F extends G[Int]

  class I extends G[String]

  def f[A[_] <: G[_],X <: Int](g: A[X]) = g

  val h: H[Int,String] = new H[Int,String]
  val g: F = new F
  val i:I = new I
  f(g) //works
  f(h) //works
  f(i) // should fail and does fail

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐