gpt4 book ai didi

scala - scala中的类型删除和继承

转载 作者:行者123 更新时间:2023-12-01 09:18:10 26 4
gpt4 key购买 nike

我有以下类层次结构。

trait Item {val id: String}

case class MItem(override val id: String, val name: String) extends Item

class DItem(override val id: String, override val name: String, val name2: String) extends MItem(id, name)

val d = new DItem("1", "one", "another one")
println(d)

预期输出

DItem(1, one, another one)

实际输出

Mitem(1,one)

为什么会这样。推荐什么以便我得到我的对象的真实类型而不是父类(super class)的类型。

最佳答案

这不是类型删除。您得到这个结果是因为 DItem 获得了从 Mitem 继承的 toString() 实现。你必须重写它才能得到你想要的

class DItem(override val id: String, override val name: String, val name2: String) extends MItem(id, name) {
override def toString = s"DItem($id, $name, $name2)"
}

所以这是一个结果:

scala> val d = new DItem("1", "one", "another one")
d: DItem = DItem(1, one, another one)

scala> println(d)
DItem(1, one, another one)

从案例类继承几乎总是一个坏主意,因为除了 toString 后继类 will also inherit equals and hashCode .

另一个缺点是此类后继类的模式匹配有限,即不可能在 case 分支中使用此类类,并可能导致令人困惑的错误。

示例

case class A(id: String)
class B(id: String, name: String) extends A(id)

new B("foo", "bar") match {
case A(id) => println(id)
case other => println(other)
}

你可能认为这段代码没有错误,但你会得到

<console>:17: error: constructor cannot be instantiated to expected type;
found : A
required: B
case A(id) => println(id)
^

但是,如果您明确地推断出 B 实例的类型,它将起作用

scala> new B("foo", "bar").asInstanceOf[A] match {
| case A(id) => println(id)
| case other => println(other)
| }
foo

所以...从案例类继承非常容易出错且令人困惑,除非您知道自己在做什么,否则应避免使用。

关于scala - scala中的类型删除和继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39198696/

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