我正在使用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.X
和C#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
有什么想法吗?
答案 0 :(得分:7)
C#X
表示来自任何X
的{{1}}。 C
表示来自特定c.X
的{{1}},即X
。后者更具体!
例如,如果C
是帐单而c
是特定客户,则X
表示该方法仅接受来自(可能是)客户c
的帐单。 c.X
表示它接受来自任何客户的任何账单。如果您想确保客户只收取自己的账单(至少在默认情况下),前者就是您想要的。
答案 1 :(得分:3)
@Rex已经对错误做了很好的解释。以下是您可以解决的问题......
如果由于类型x
而返回c.X
是合理的(即,X
类型的特定c
类型的值作为参数,然后你可以收紧它的类型作为参数,
def bar[C <: Container](c: C)(x: c.X): c.X = x
现在,bar只接受X
类型的值,这些值与特定值c
相关。如果这在酒吧的呼叫站点不起作用,那么您将需要重新设计您的设计。
答案 2 :(得分:2)
c.X
和C#X
绝对不一样 - 如果是,为什么两者都存在?
考虑一下a
和b
C
的不同实例的情况。根据定义,a.X
和b.X
不同,但都是C#X
。