我在scala中运行了一些使用Singleton的示例,并且遇到了看似不一致的问题。这是一个最小的例子:
trait X {
type T <: Inner
trait Inner {
def innerMethod(config: T)
}
def outerMethod(config: T)
}
如果我这样做
def add[U <: X](a: U#T, b: U#T) = {
a.innerMethod(b)
}
无法按预期编译,因为a
可以是obj1.T
类型而b
可以是obj2.T
类型,可以U
约束Singleton
{1}}解决了问题:
def add[U <: X with Singleton](a: U#T, b: U#T) = {
a.innerMethod(b)
}
但是,以下内容也无法编译:
def add[U <: X with Singleton](a: U, b: U#T) = {
a.outerMethod(b)
}
错误是:
错误:(15,21)类型不匹配;
发现:b.type(底层类型为U#T)
必需:a.T
似乎Singleton约束会强制U
为a.type
类型,然后b
类型为a.T
。
知道发生了什么事吗?
答案 0 :(得分:0)
我认为你期望T是对象无关的类型,而不是:对于类型X的每个对象,都有唯一的抽象T类型。
对于outerMethod,
def outerMethod(X#T) = ...
应该够了, 对于innerMethod,调用函数的对象类型应该是相同的X#T。
检查出来
class Outer {
type T<: Inner
class Inner {
def that(that:Outer#T) = that
}
def that(that:Outer#T) = that
}
class Outer2 extends Outer{
type T = Inner
val in = new T
}
object Obj {
def add[U <: Outer](a: U#T, b: U#T) = {
a.that(b)
}
def add[U<:Outer](a:U, b: U#T): Unit = {
a.that(b)
}
}
val out = new Outer2
Obj.add(out.in, out.in)
Obj.add(out, out.in)