繁体   English   中英

Scala案例类层次结构

[英]Scala case class hierarchy

我在设计案例课时遇到了一些困难。 简化版看起来像:

abstract class Base(s: Option[String]) {
   //code
}

case class CaseClass(s: Option[String] = None) extends Base(s) {
    //code
}

我有一个方法,我想做的事情如下:

  def method(base : Base) = {
     //code
     base copy (s = Some("string"))
  }

我当然得到:

 value copy is not a member of Base

所以我想要做的是基于我的基类(不是案例类)创建一个新实例。 显然,人们不能这样做。 但是你如何以优雅的方式解决这个问题呢?

提前致谢!

如果参数化基类并在那里定义抽象复制方法,则可以让子类从复制方法返回自己类型的实例。 在这种情况下,您希望CaseClass返回一个CaseClass。

abstract class Base[T](s: Option[String]) {
  def copy(in: Option[String]) : T
}

case class CaseClass(s: Option[String]) extends Base[CaseClass](s) {
  def copy(in: Option[String]) = CaseClass(in)
}

case class OtherClass(s: Option[String]) extends Base[OtherClass](s) {
  def copy(in: Option[String]) = OtherClass(in)
}

def method[T <: Base[T]](base: T) : T = {
  base.copy(Some("String"))
}


scala> method(CaseClass(None))
res1: CaseClass = CaseClass(Some(String))

scala> method(OtherClass(Some("hi")))
res2: OtherClass = OtherClass(Some(String))

Base的其他子类将返回自己的类型。 #method上的类型参数定义为Base [T]的上限。 这意味着T必须是Base [T]的任何子类型,并且允许您将CaseClass和OtherClass的实例作为参数提供给该方法。

您尝试实现的行为无法实现。 case类的copy方法由编译器自动生成,一旦你将一个名为copy的方法添加到你的实现中,编译器就不会生成任何糖。

您可以使用traits重新实现copy ,但它不会像生成的那样灵活(每次case类的字段集更改时,您将不得不更新基本特征, copymethod实现):

sealed trait Base[T] {
   val s: Option[String]
   def copy(s: Option[String]) : T
}

case class CaseClass(override val s: Option[String] = None) extends Base[CaseClass] {
    override def copy(s: Option[String]) = CaseClass(s)
}

def method[T <: Base[T]](base : Base[T]) = base copy (s = Some("strng"))

或者,您可以按如下方式实现method

case class CaseClass(s: Option[String] = None)

def method[X <: {def copy(s: Option[String]):X}](base : X) = 
    base copy(s = Some("string"))

scala> method(CaseClass())
res4: CaseClass = CaseClass(Some(string))

因此,如果您的案例类发生变化,您将不需要Base特征,并减少更改次数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM