使用依赖方法类型和类型投影时的类型等效问题



我正在Scala 2.10.0-M1中尝试以下操作:

trait Container {
  type X
}
class Test[C <: Container](val c: C) {
  def foo(x: c.X): C#X = x // this compiles fine
  def bar(x: C#X): c.X = x // this does not compile
}

使用此表单时问题相同:

def bar[C <: Container](c: C)(x: C#X): c.X = x

我真的不明白为什么foo编译而bar不编译。

我认为c.XC#X在这里应该是相同的。

此外,我不理解错误消息:

[error]  found   : x.type (with underlying type C#X)
[error]  required: Test.this.c.X
[error]  possible cause: missing arguments for method or constructor
[error]   def bar(x: C#X): c.X = x // this does not compile

知道吗?

C#X表示来自任何CXc.X是指来自特定CX,即c。后者要具体得多!

例如,如果X是一张账单,而c是一个特定的客户,那么c.X意味着该方法只接受来自(可能是)客户c的账单。C#X表示接受任何客户的任何账单。如果你想确保客户只收取自己的账单(至少在默认情况下),前者就是你想要的。

@Rex很好地解释了问题所在。以下是如何修复它。。。

如果能够作为类型c.X的结果返回x(即作为参数传递的特定cX类型的值)是合理的,那么可以将其类型作为参数

def bar[C <: Container](c: C)(x: c.X): c.X = x

现在栏将只接受与特定值c相关的类型为X的值。如果这对你在酒吧的呼叫站点不起作用,那么你需要重新设计。

c.XC#X肯定不一样——如果是,为什么两者都存在?

考虑这样一种情况,即abC的不同实例。根据定义,a.Xb.X是不同的,但都是C#X

最新更新