使用“type"关键字和路径依赖类型覆盖类型 [英] Overriding types using 'type' keyword and path-dependant types
问题描述
假设我有这样的代码:
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) 不应该是类型错误吗?
I don't get why this compiles. Shouldn't jsonHolder.put(valueOfXml) by a type error?
如果我改变了
type Value
像这样:
case class Value(content:String)
并删除覆盖行,其他所有内容都会保留,因为它实际上会显示类型不匹配错误.
and remove the override lines and everything else stays as it is type mismatch error will actually show up.
那么这两者之间有什么区别,因为 put 参数的声明不必更改并且行为完全不同?
So what is the difference between those two, since declaration of put argument does not have to change and the behavior is completely different?
推荐答案
好吧,这不是类型错误,因为 JsonHolder.Value
和 XmlHolder.Value
都是 <代码>字符串s.将 type
视为其他类型的别名.所有类型都替换为其实际类型.所以你的代码大致是这样的:
Well, that's not a type error, because both JsonHolder.Value
and XmlHolder.Value
are String
s. Consider the type
an alias for an other type. All types are replaced with their actual types. So your code roughly looks like this:
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
,那么您肯定会收到编译错误:
If one of your types would be, for example, an Int
then sure you'd get a compilation error:
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)
}
}
这篇关于使用“type"关键字和路径依赖类型覆盖类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!