Scala:如何使用默认值初始化对象

Scala:如何使用默认值初始化对象,scala,constructor,default-value,Scala,Constructor,Default Value,我想用一个例子可以更好地解释这一点 我有下面的案例课 case class Person(name: String = "no name", surname: String = "no surname") 我想创建一个通用函数来填充它,例如,json消息,它可能不会指定所有字段 我知道要使用默认值,简单的答案不是将它们传递给构造函数,但是如果我有几个字段可能出现在json中,也可能不出现在json中,那么我应该使用一个巨大的switch语句来覆盖所有可能丢失的参数组合。在这种情况下,在阅读了j

我想用一个例子可以更好地解释这一点

我有下面的案例课

case class Person(name: String = "no name", surname: String = "no surname")
我想创建一个通用函数来填充它,例如,json消息,它可能不会指定所有字段

我知道要使用默认值,简单的答案不是将它们传递给构造函数,但是如果我有几个字段可能出现在json中,也可能不出现在json中,那么我应该使用一个巨大的switch语句来覆盖所有可能丢失的参数组合。在这种情况下,在阅读了json之后,我应该注意现在的姓名和姓氏、没有姓名、没有姓氏和没有姓名或姓氏的情况。。。(哎呀,我希望我说清楚了)

更准确地说,我正在尝试开发一个函数,允许我从以下json值创建一个人,在缺少一些参数时使用默认值

{ "name": "john", "surname": "doe" }
{ "surname": "doe" }
{ "name": "john" }
{ }
这就是为什么我在寻找一种更通用的方法来处理这个问题

(我将展示一些要给出的伪代码以及我试图实现的想法)

我在想这样的事情:

val p = Person(name= "new person name", surname= Unit)
在这种情况下,姓氏应该得到默认值

或者类似的

val p = Person( Map( "name" -> "new person name" ) _* )
因此,它还采用姓氏的默认值

或者在构造函数中执行此操作,如果检测到空值(或无),则可以指定默认值

事实上,我试图避免重复默认值的定义


无论如何,实现这一点最惯用的方法是什么?

如果希望使用默认值,通常只需省去命名参数:

scala> val p = Person(name = "new person name")
p: Person = Person(new person name,no surname)
但是,由于您希望明确知道值是否应为默认值,因此可以在构造函数中实现基于映射的想法。如果不想重复默认设置,那么以下两个选项如何:

选项1:默认值的外部化常量 从外部设置默认值。在主构造函数和基于映射的构造函数中都使用它们

val nameDefault = "no name"
val surnameDefault = "no surname"

case class Person(name: String = nameDefault, surname: String = surnameDefault) {
  def this(m: Map[String, String]) =
    this(m.getOrElse("name", nameDefault), m.getOrElse("surname", surnameDefault))
}
用法:

new Person(name = "new person name", surname = "new person surname")
new Person(Map("name" -> "new person name"))
new Person(name = "new person name")
new Person(name = "new person name", surname = "new person surname")
new Person(Map("name" -> "new person name"))
new Person(name = Some("new person name"))
new Person(name = "new person name") // can't do this
选项2:可选替代构造函数 您可能会发现这有点干净,因为它不依赖外部化常量。这里唯一的缺点是,如果只想使用一些参数进行构造,则必须将每个参数包装在
some()

用法:

new Person(name = "new person name", surname = "new person surname")
new Person(Map("name" -> "new person name"))
new Person(name = "new person name")
new Person(name = "new person name", surname = "new person surname")
new Person(Map("name" -> "new person name"))
new Person(name = Some("new person name"))
new Person(name = "new person name") // can't do this

我认为这两种方法都是有用的。您可以使用两种类型指定其中一种

val name: Eiter[String, Unit] = Left("name")
val surname: Either[String, Unit] = Right( () )

现在,您可以检查是左还是右,并使用所需的参数调用构造函数。

谢谢dhg,我理解这一点,但我需要一个通用函数来加载可能不存在的值,我编辑了该问题以澄清问题problem@opensas,我现在明白了。我更新了两个选项,这可能正是您想要的。答案很好,我想我更喜欢第一种方法,在Person companion对象中设置常量,只是为了让它们少一些外部性…+1表示选项#1。但是,我认为选项#2也是选项#1的+1,创造性地使用了带有Map param的alt构造函数。json或servlet参数非常适合这里,我试图避免使用每个可能存在/缺少的参数组合调用构造函数。。。我不知道我是否跟着你。。。