Scala:为什么抽象类型成员等于类型参数=:=不等于使用?

时间:2017-07-04 20:05:29

标签: scala generics types

我开始在类型参数上使用抽象类型成员 - 主要是因为它们似乎对我的类型推断更好。但是,我仍然在努力理解如何从它们定义的类型之外使用它们。例如,我无法理解为什么以下Scala程序不应该编译:

class A;

直观地说,我希望需求trait Thing trait Describer { type X<:Thing def describe(x:X) = println(x) } object Program extends App { def print[T <: Thing, D <: Describer] (describer: D, thing:T) (implicit ev: D#X =:= T) = describer.describe(thing) } 可以保证两种类型确实相等,因此两个实例可以互换使用,但是我得到了这个编译错误:

D#X =:= T

我误解了什么?还有另一种方法可以做我想做的事吗?或者如果失败,将error: type mismatch; found : thing.type (with underlying type T) required: describer.X = describer.describe(thing) 强制转换为所需类型(thing)是否安全?

1 个答案:

答案 0 :(得分:5)

describer.describe的参数类型实际上是describer.X而不是D#X。您必须知道的另一件事是A =:= B也可以作为从AB的转换,但(至少目前)不是相反的转换。所以以下内容应该有效。

def print[T <: Thing]
  (describer: Describer, thing: T)
  (implicit ev: T =:= describer.X) 
  = describer.describe(thing)