使用“type"关键字和路径依赖类型覆盖类型 [英] Overriding types using 'type' keyword and path-dependant types

查看:22
本文介绍了使用“type"关键字和路径依赖类型覆盖类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有这样的代码:

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.ValueXmlHolder.Value 都是 <代码>字符串s.将 type 视为其他类型的别名.所有类型都替换为其实际类型.所以你的代码大致是这样的:

Well, that's not a type error, because both JsonHolder.Value and XmlHolder.Value are Strings. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆