gpt4 book ai didi

scala - 案例类继承另一个类/特征

转载 作者:行者123 更新时间:2023-12-02 08:01:48 29 4
gpt4 key购买 nike

我想让一个案例类扩展一个特征

以下是我的要求:

  • 我需要为 child 使用案例类。这是一个硬性要求,因为 scopt ( https://github.com/scopt/scopt )
  • parent 需要是一个特质。很抱歉之前没有说清楚
  • 我希望 child 可以访问父特征的属性,并且最好在声明子案例类时不必再次指定它们。例如,如果父特征是:trait ParentParams { var name: String = "Al" }那么 child 不应该是case class ChildParams(id: String = "whatever", override val name: String = Parent.defaultName) extends Parent .我更愿意将其设为 case class Child(id: String) extends Parent .但是,当我尝试第二种方法时,当我尝试执行 .copy() 时,我无法访问名称字段。在案例类对象上。作为一种解决方法,我可以改变 name 的值属性通过 childObj.name = "newName"
  • 我应该(硬要求)能够覆盖子对象从父对象继承的属性值。现在这是可能的,因为我已将父属性声明为 var而不是一个 val。但是,理想情况下,我想让它不可变并使用复制方法来更改值。

  • 这是我现在拥有的,但无法使用 .copy()方法来更改继承属性的值。
    package abcd.wxyz

    import org.scalatest.{FlatSpec, Matchers}

    trait ParentTrait {
    var name: String = "name"
    }

    case class TestParams(param1: String = "123") extends ParentTrait

    class TestParamsSpec extends FlatSpec with Matchers {
    "TestParams" should "be able to access it's inherited attributes and modify them" in {

    val testParams = TestParams()
    testParams.name = "newName1"
    testParams.param1 should equal("123")
    testParams.name should equal("newName1")

    val modifiedTestParams = testParams.copy(name = "newName2") // cannot resolve symbol name
    modifiedTestParams.name should equal("newName2")

    }
    }

    我在 .copy(name = "newName2") 上收到“无法解析符号名称”对于上面的代码。

    拥有这种继承的原因是有一个函数接受一个子对象并期望它定义一个“名称”属性。例如,考虑一个将附加“先生”的函数。或“夫人”给定一个具有 name 属性的 Child 对象。

    正在发生的事情的总体背景:
    我正在使用 scopt 使用命令行输入值(进入案例类)填充配置。如果未提供任何值,则为该属性使用默认值。属性是指案例类中的数据成员。
    我有一个函数(我们称之为 dbReader),它接受案例类的对象并使用它来建立连接并从数据库中读取。我的项目中有许多不同的参数案例类,我希望这些参数中的每一个都实现一个通用的 DatabaseConnectionParameters trait 以便函数 dbReader 可以工作,而不管将哪个参数 case 类传递给它。

    最佳答案

    在 scala 中,构造函数的默认值被编译为在伴随对象的上下文中计算的函数,所以

    case class CaseClazz(foo: String = super.bar) extends Bar

    编译成类似的东西(为了清楚起见,我没有修改名称):
    class Bar { def bar: String = "whatevs" }

    case class CaseClazz(foo: String = CaseClazz.defaultForFoo) extends Bar

    object CaseClazz extends Function1[String, CaseClazz] {
    def defaultForFoo: String = super.bar
    def apply(foo: String = defaultForFoo): CaseClazz = new CaseClazz(foo)
    }

    哪个不能编译,因为 super对象中是 CaseClazz$ ,它没有定义 bar方法。

    获得您寻求的行为的最清晰方法是 IMO:
    object Parent {
    val defaultName: String = "Al"
    }

    class Parent(val name: String = Parent.defaultName) { def parentBehavior: Unit = println("parent!") }

    case class Child(id: String = "55", override val name: String = Parent.defaultName) extends Parent(name)

    这使得:
    scala> Child(id = "ego").parentBehavior
    parent!

    scala> Child(id = "ego").name
    res12: String = Al

    scala> Child().name
    res13: String = Al

    scala> Child().parentBehavior
    parent!

    关于scala - 案例类继承另一个类/特征,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56345223/

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