我对使特定类型符合更一般的结构类型的问题感兴趣。考虑以下示例:
trait Sup
trait Sub extends Sup
type General = {
def contra(o: Sub): Unit
def co(): Sup
def defaults(age: Int): Unit
def defaults2(age: Int): Unit
def defaults3(first: String): Unit
}
trait Specific {
def contra(o: Sup): Unit // doesn't conform
def co(): Sub // conforms
def defaults(age: Int, name: String = ""): Unit // doesn't conform
def defaults2(name: String = "", age: Int = 0): Unit // doesn't conform
def defaults3(first: String = "", last: String = ""): Unit // doesn't conform
}
在每一种不符合要求的情况下,对 in 方法的调用都General
可以安全地解析为 in 中的相应方法Specific
。在这个问题中可以找到一个更有趣的实际示例:
trait Versionable[T] {
self: { def copy(version: Int): T } =>
val version = 0
def incrementVersion = copy(version = version + 1)
}
case class Customer(name: String, override val version: Int)
extends Versionable[Customer] {
def changeName(newName: String) = copy(name = newName)
}
这里,Customer 的copy
方法不符合 Versionable 的 self-type annotation 中的签名。但是请注意,如果编译器允许,copy
可以像在Versionable.incrementVersion
. 显然,Customercopy
方法的实际签名对于在 Versionable 中使用来说太具体了,因为它带有不相关的知识,即可以选择提供name
参数。
有没有办法解决这些限制?有没有理由认为这种普遍的一致性是一个坏主意?