错误如下所示:
trait Base { type T }
trait Component { self: Base =>
override type T <: MyT
val factory: Factory
trait Factory { def get_t: T }
trait MyT { def xxx: Unit }
class User {
val t: T = factory.get_t
def yyy = t.xxx
}
}
trait ComponentImpl { self: Component =>
type T = TImpl
class TImpl extends MyT {
def xxx = println("xxx")
}
val factory = new Factory {
def get_t: T = new TImpl
}
}
我收到错误:
<console>:26: error: value xxx is not a member of Component.this.T
def yyy = t.xxx
有了一些冗余,我还发布了@slouc和@Kolmar建议的最小例子
trait Base { type T }
trait MyT { def xxx: Unit }
trait Component { self: Base =>
override type T <: MyT
val t: T
def yyy = t.xxx // error
}
似乎我无法利用约束给出的增量,部分知识。
我的问题不是关于方法,而是我有兴趣了解错误背后的原因。
为了提供更多上下文,我还要补充一点,当我尝试将继承关系转换为两个组件之间基于自我类型的关系时,我遇到了这个问题。
答案 0 :(得分:2)
使用自我类型注释,您基本上告诉编译器自引用具有不同的类型
self: Base
如果你使用任何普通表达式执行此操作,那么现在唯一的类型就是Base。不知何故,类型注释作为特殊情况处理并保持其原始类型,我们实际上看起来的类型是
self: Base with Component
现在,不知怎的,如果你引用Component.this似乎在被覆盖的类型成员的情况下丢失了这些信息(或者可能覆盖错误的方法,但我看不出任何解释这不是一个bug)
现在,如果您实际注释此类型,问题就会消失:
trait Component { self: Base with Component => ... }
这也清楚地表明这是一个错误,因为这很好用:
trait Component { self: Base =>
val v: Base with Component = self
}
这实际上是一个已知的Bug:
https://issues.scala-lang.org/browse/SI-7255?jql=text%20~%20%22override%20self%20type%20abstract%22
答案 1 :(得分:1)
有趣的问题。这是一个简单的例子:
scanf()
请注意以下三点:
1.将自我类型注释更改为继承可以解决所有问题:
trait Base { type T }
trait MyT { def xxx: Unit }
trait Component { self: Base =>
override type T <: MyT
val t: T
def yyy = t.xxx // error
}
2.自我类型的超越方法没有问题:
trait Component extends Base {
override type T <: MyT
val t: T
def yyy = t.xxx
}
3.如果不是缩小类型T而是使其具体化,那么最重要的是:
trait Base { def foo }
trait Component { self: Base =>
override def foo = println("foo")
}
所以,我对问题的表述是 - 为什么在继承的情况下,所有三种情况都可以正常工作(1.覆盖方法,2。通过缩小覆盖抽象类型成员,3。通过制作覆盖抽象类型成员具体),但在自我类型的情况下第二种情况是有问题的,而其他两种工作正常吗?
考虑修改您的问题(删除trait Base { type T }
trait Component { self: Base =>
override type T = List[Int]
val t: T
def yyy = t.reverse
}
,ComponentImpl
等),以便为其他读者简化。