gpt4 book ai didi

scala - 为什么 var 在 Scala 中编译 val 时会导致类型差异错误?

转载 作者:行者123 更新时间:2023-12-04 19:44:12 26 4
gpt4 key购买 nike

scala> case class Data[+T](val value:T=null)
defined class Data

scala> val foo=Data[ArrayBuffer[Data[Any]]]()
foo: Data[scala.collection.mutable.ArrayBuffer[Data[Any]]] = Data(null)

scala> foo.value+=Data[String]()
java.lang.NullPointerException
... 33 elided

我想要一个实例化为 Data[String]、Data[ArrayBuffer[Data[Any]]] 或 Data[Map[String,Data[Any]]] 的 Data 类。在上面的示例中,我尝试将其实例化为 Data[ArrayBuffer[Data[Any]]] 并将 Data[String] 添加到其数组缓冲区。当然我得到一个空指针异常,因为值是空的。但是这个例子的重点是它至少可以编译和运行。

现在,在 Data 构造函数中,我想根据初始空值的类型将值实例化为 Data[String]、ArrayBuffer[Data[Any]] 或 Map[String,Data[Any]]由 getClass 方法返回。然而,为此我需要 value 是一个 var,这样我就可以在检查其 null 值的类型后修改它。

但是我得到这个错误:

scala> case class Data[+T](var value:T=null)
<console>:11: error: covariant type T occurs in contravariant position in type T of value value_=
case class Data[+T](var value:T=null)

最佳答案

使您的DataT 中保持不变。只需删除 +: Data[T] - 这应该可以编译。更好的是,重新考虑您的设计以摆脱空值和可变变量 - 它们都有异味。

编辑:在阅读了您的评论后,我更好地理解了您的意图。例如,考虑这样的事情作为选项之一。

sealed trait Node 
case class ListNode(list: Seq[Node]) extends Node
case class MapNode(map: Map[String, Node]) extends Node
case class LeafNode(data: String) extends Node

现在您可以用类似的东西解析您的文档(这是“伪代码”,将其调整为您正在使用的任何 xml 解析库):

def parseNode(tag: XMLTag): Node = tag.tagType match {
case LIST =>
val subNodes = tag.getNestedTags.map(parseNode)
ListNode(subNodes)
case MAP =>
val subNodes = tag.getNestedTags.map { tag =>
tag.name -> parseNode(tag)
}
MapNode(subNodes.toMap)
case _ =>
LeafNode(tag.text)
}

关于scala - 为什么 var 在 Scala 中编译 val 时会导致类型差异错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34576858/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com