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

标签 scala 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) 不应该是类型错误吗?

如果我改变

type Value

像这样:

case class Value(content:String)

并删除覆盖行,其他所有内容保持原样,类型不匹配错误将实际显示。

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

最佳答案

嗯,这不是类型错误,因为 JsonHolder.ValueXmlHolder.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/

相关文章:

scala - Spark build.sbt 文件版本控制

Scala:Option.getOrElse(...) 的默认返回类型

c# - 动态设置泛型类型参数

java - 如何以全精度输出本地化的 Java 浮点值?

c# - 如何获取 Nullable<T> 实例的类型

java - 与 Double.TYPE 和 Double.class 的比较

list - Haskell 中的 [] (列表构造函数)是什么?

Python+Tornado vs Scala+Lift?

scala - 帮助 Drools 与 Scala 集成

scala - 为什么在我使用 com.databricks.spark.avro 时必须添加 org.apache.spark.avro 依赖才能在 Spark2.4 中读/写 avro 文件?