简体   繁体   中英

trait with method returning copy of trait

I want to create a method in a trait that returns a copy of the trait so something like this:

sealed trait thing {
  def attr1: String
  def attr2: String
  def paste(middle: String) : String = {
    return attr1 + middle + attr2;
  }
  //def new_thing(addOn: String) : thing = {
    // create new thing with addOn pasted to end of attr1 and attr2, but with other attributes preserved
 // }
}

case class objectA(
  attr1: String,
  attr2: String,
  attrA: String
) extends thing

case class objectB(
  attr1: String,
  attr2: String,
  attrB: String
) extends thing

object example {
  def main(args: Array[String]) = {
    val x = objectA("A", "B", "C")
    val y = x.new_thing("Z")
    // should return 'y: objectA = objectA(AZ, BZ, C)
  }
}

Creating a method in the case clase that does this is straight forward.

case clase objectA(
  attr1: String
  attr2: String
  attrA: String

) extends thing {
    def new_thing(addOn: String) : objectA = {
      return objectA(attr1 + addOn, attr2 + addOn, attrA)
    }
}

But since sealed traits have a copy method (edit no they don't) I feel like I shouldn't have to implement new_thing for each case class.

I am learning Scala so it is possible I am missing something obvious. Is this a case where I want to use F-bounded polymorphism? What is the most Scala way of dealing with this?

What I would do is to define the trait likewise (using return is discouraged):

sealed trait thing {
  def attr1: String
  def attr2: String
  def paste(middle: String): String = attr1 + middle + attr2
  def new_thing(addOn: String): thing
}

And then, for each case class I'll just override new_thing with the implementation I'm looking for:

case class objectA(attr1: String, attr2: String, attrA: String) extends thing {
  override def new_thing(addOn: String): objectA =
    objectA(attr1 + addOn, attr2 + addOn, attrA)
}

Therefore, you can proceed likewise:

scala> val a: objectA = objectA("a", "b", "c")
a: objectA = objectA(a,b,c)

scala> val b: objectA = a.new_thing(" plus a")
b: objectA = objectA(a plus a,b plus a,c)

scala> b
res0: objectA = objectA(a plus a,b plus a,c)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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