使用'type'关键字和路径相关类型覆盖类型

alm*_*dar 2 types scala

假设我有一个像这样的代码:

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)
  }
}
Run Code Online (Sandbox Code Playgroud)

我不明白这为什么编译.jsonHolder.put(valueOfXml)不应该出现类型错误吗?

如果我改变

type Value
Run Code Online (Sandbox Code Playgroud)

这样的事情:

case class Value(content:String)
Run Code Online (Sandbox Code Playgroud)

并删除覆盖线和其他所有内容,因为它实际上会显示类型不匹配错误.

那么这两者之间有什么区别,因为put参数的声明不必改变,行为完全不同?

ser*_*jja 5

好吧,这不是一个类型的错误,因为这两个JsonHolder.ValueXmlHolder.ValueString秒.考虑type其他类型的别名.所有类型都被替换为实际类型.所以你的代码大致如下:

val valueOfJson = new String("AAA") // JsonHolder.Value is a String
val valueOfXml = new String("AAA") // XmlHolder.Value is a String as well
Run Code Online (Sandbox Code Playgroud)

像这样:

class JsonHolder extends Holder {
  def put(v: String): Unit = {}
}

class XmlHolder extends Holder {
  def put(v: String): Unit = {}
}
Run Code Online (Sandbox Code Playgroud)

例如,如果您的某个类型是,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)
  }
}
Run Code Online (Sandbox Code Playgroud)