轻松创建案例 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])
,仅此而已。我个人不喜欢使用默认参数或隐式转换,因为当我这样做时,事情会爆炸。
假设我有以下代码。假设为语法糖提供了替代构造函数(假设这是一项要求):
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])
,仅此而已。我个人不喜欢使用默认参数或隐式转换,因为当我这样做时,事情会爆炸。