Как создать экземпляр класса Scala, используя все атрибуты класса с меньшим регистром? - PullRequest
1 голос
/ 25 марта 2020

У меня есть экземпляр класса дела A:

case class A(
  foo: String,
  bar: String,
  baz: String
)
val a = A("a", "b", "c")

Я хочу использовать это для создания экземпляра класса дела B с атрибутами, которые являются надмножеством A:

case class B(
  foo: String,
  bar: String,
  baz: String,
  qux: String,
  quux: String
)

Есть ли более элегантный способ сделать это, чем val b = (A.foo, A.bar, A.baz, "d", "e")? Я должен сделать это несколько раз в своем коде, и мой фактический вариант использования имеет что-то вроде 20 параметров, поэтому очевидный способ очень длинный.

Ответы [ 3 ]

3 голосов
/ 25 марта 2020

Во-первых, case class с 20 параметрами обычно является признаком плохого дизайна, поэтому подумайте о том, чтобы сгруппировать эти параметры в более мелкие классы и затем объединить их в контейнерный класс.

Если сохранить этот дизайн и вы не хотите использовать внешние библиотеки, вы можете создать конструктор для B, который принимает A плюс дополнительные параметры:

object B {
  def apply(a: A, qux: String, quux: String): B = B(a.foo, a.bar, a.baz, qux, quux)
}

val a:A = ???
val b = B(a, "qux", "quux")
2 голосов
/ 25 марта 2020

Вы можете определить одно или несколько неявных преобразований.

implicit class A2B(a:A) {
  def toB(x:String, y:String) :B = B(a.foo,a.bar,a.baz,x,y)
  //other conversion methods here
}

val a = A("a", "b", "c")  //a: A = A(a,b,c)
val b = a.toB("d", "e")   //b: B = B(a,b,c,d,e)
1 голос
/ 25 марта 2020

Полагаю, Хенкан делает именно то, что вы хотите.

import henkan.convert.Syntax._

val b:B = A("a", "b", "c").to[B].set(qux = "d", quux = "e")

Хенкан использует бесформенное под капотом, так что вы также можете использовать его для написания своих собственных решений.

...