我对使特定类型符合更通用的结构类型的问题感兴趣。考虑以下示例:
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
}
在每种不符合要求的情况下,都会调用以下方法General
可以安全地解析为相应的方法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)
}
在这里,客户的copy
方法不符合 Versionable 的自类型注释中的签名。但请注意,如果编译器允许,copy
可以像在中那样调用Versionable.incrementVersion
。显然,客户的实际签名copy
方法对于在版本化中使用来说过于具体,因为它携带了不相关的知识,人们可以选择提供一个name
范围。
有办法解决这些限制吗?是否有理由认为这种普遍的一致性是一个坏主意?
一个问题是,当您阅读这段代码时:
self: { def copy(version: Int): T }
您不希望参数的名称很重要,因为在本例中它必须如此:
case class Robot(number: Int, override val version: Int)
extends Versionable[Robot]
EDIT:另一方面,关于方法缺乏参数逆变,您可以这样做:
type General = { val contra: (Sub => Unit) }
class B { val contra = ((o:Sup) => println(o)) }
var b:General = new B
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)