假设我有这样一段代码:
trait Holder {
type Value
def put(v:Value)
}
class JsonHolder extends Holder {
override type Value = String
def put(v: JsonHolder.this.Value): Unit = {}
}
class XmlHolder extends Holder {
override type Value = String
def put(v: XmlHolder.this.Value): Unit = {}
}
object Foo {
def main(args: Array[String]) {
val jsonHolder = new JsonHolder
val xmlHodler = new XmlHolder
val valueOfJson = new jsonHolder.Value("AAA")
val valueOfXml = new xmlHodler.Value("AAA")
jsonHolder.put(valueOfXml)
}
}
我不明白为什么会这样编译。 jsonHolder.put(valueOfXml) 不应该是类型错误吗?
如果我改变
type Value
像这样:
case class Value(content:String)
并删除覆盖行,其他所有内容保持原样,类型不匹配错误将实际显示。
那么这两者之间有什么区别,因为 put 参数的声明不必更改并且行为完全不同?
最佳答案
嗯,这不是类型错误,因为 JsonHolder.Value
和 XmlHolder.Value
都是 String
。将 type
视为另一种类型的别名。所有类型都替换为它们的实际类型。所以你的代码大致是这样的:
val valueOfJson = new String("AAA") // JsonHolder.Value is a String
val valueOfXml = new String("AAA") // XmlHolder.Value is a String as well
像这样:
class JsonHolder extends Holder {
def put(v: String): Unit = {}
}
class XmlHolder extends Holder {
def put(v: String): Unit = {}
}
例如,如果您的类型之一是 Int
,那么肯定会出现编译错误:
class JsonHolder extends Holder {
override type Value = Int
def put(v: JsonHolder.this.Value): Unit = {}
}
class XmlHolder extends Holder {
override type Value = String
def put(v: XmlHolder.this.Value): Unit = {}
}
object Foo {
def main(args: Array[String]) {
val jsonHolder = new JsonHolder
val xmlHodler = new XmlHolder
//compilation error here - Int doesn't have a String constructor
val valueOfJson = new jsonHolder.Value("AAA")
val valueOfXml = new xmlHodler.Value("AAA")
jsonHolder.put(valueOfXml)
}
}
关于scala - 使用 'type' 关键字和路径相关类型覆盖类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21306233/