轻松创建案例 Class 替代构造函数的所有组合

Creating all Combinations of a Case Class Alternative Constructor Easily

假设我有以下代码。假设为语法糖提供了替代构造函数(假设这是一项要求):

object Example extends App {
  case class Doggy(name: Option[String] = None, age: Option[Int] = None)

  object Doggy {
    def apply(name: String): Doggy = Doggy(name = Some(name))
    def apply(age: Int): Doggy = Doggy(age = Some(age))
    def apply(name: String, age: Int): Doggy = Doggy(name = Some(name), age = Some(age))
  }


  val rex = ("rex", 10)
  val pex = ("pex")
  val tex = (100)
}

如您所见,备用构造函数提供语法糖,允许用户跳过编写 Some(name) 或 Some(age) 等。

现在在这个案例的用例中class,用户可以使用构造函数的所有可能组合。

对于具有许多不同选项的情况 class,通过定义 apply() 构造备用构造函数很快变得笨拙。

有没有办法以某种方式以编程方式生成 apply() 的所有组合?

例如,这是一个堆栈溢出问题,其中将列表传递给构造函数:Link。我们可以生成列表的所有组合,并在每个组合上定义一个 apply() 吗?

我意识到这可能是不可能的,但我们将不胜感激任何指导(甚至可能是改进所提供的代码模式的方法)

编辑:

我目前只在伴随对象中定义以下内容:

implicit def toOption[T](x: T): Option[T] = Option[T](x)

您可以利用 copy 在没有 args 构造函数的情况下创建的单例。假设 Doggy 有一个无参数的构造函数,你可以在对象中创建一个实例并使用 copy 来获取具有不同参数的其他实例:

object Doggy {

  val instance = Doggy()

  def main(args: Array[String]): Unit = {
    val doggy1 = instance.copy(name = "Name")
    val doggy1 = instance.copy(age = 1)
    val doggy1 = instance.copy(name = "Name", age = 1)
    val doggy1 = instance.copy(age = 1, name = "Name")
  }

}

请注意,为了便于阅读,我省略了 Option

广告你可以看到,你可以以任何顺序向copy方法提供任何参数。

您可以为伴随对象的 apply 方法使用具有默认值的参数,但正如@Luis Miguel Mejia Suarez 所说,每次使用 Some 会更好(甚至可能更容易)。

case class Doggy(name: Option[String], age: Option[Int])

object Doggy {
  def apply(name: String = null, age: Int = -1): Doggy =
    Doggy(Option(name), if (age == -1) None else Some(age))
}

然后你可以像这样使用它:

val rex = Doggy(name = "rex", age = 10)
val pex = Doggy(name = "pex")
val tex = Doggy(age = 100)

不过老实说,我只会使用 case class Doggy(name: Option[String], age: Option[Int]),仅此而已。我个人不喜欢使用默认参数或隐式转换,因为当我这样做时,事情会爆炸。