Scala:如何使用默认值初始化对象
Posted
技术标签:
【中文标题】Scala:如何使用默认值初始化对象【英文标题】:Scala: how to initialize an object using default values 【发布时间】:2012-05-15 09:51:14 【问题描述】:我认为这可以通过一个例子来更好地解释
我有以下案例类
case class Person(name: String = "no name", surname: String = "no surname")
我想创建一个通用函数来填充它,例如,一个 json 消息,它可能不会指定所有字段
我知道要使用默认值,简单的答案是不要将它们传递给构造函数,但是如果我有几个字段可能会出现在 json 中,也可能不会出现,我应该使用一个巨大的 switch 语句覆盖每个可能的缺失参数组合。在这种情况下,在阅读完json之后,我应该注意name & surname present,no name,no surname and no name or surname case...(哎呀,我希望我说清楚了)。
更准确地说,我正在尝试开发一个函数,允许我从以下 json 值创建一个人,当缺少某些参数时使用默认值
"name": "john", "surname": "doe"
"surname": "doe"
"name": "john"
这就是为什么我正在寻找一种更通用的方法来处理这个问题。
(我将展示一些伪代码来说明我想要实现的目标)
我在想这样的事情:
val p = Person(name= "new person name", surname= Unit)
在这种情况下 surname 应该得到默认值
或者类似的东西
val p = Person( Map( "name" -> "new person name" ) _* )
这样它也采用默认的姓氏
或者也许在构造函数中这样做,如果我检测到一个空值(或无),我可以分配默认值。
其实我是在尽量避免重复默认值的定义。
无论如何,实现这样的事情最惯用的方法是什么?
【问题讨论】:
【参考方案1】:如果您想使用默认值,您通常只需省略该命名参数:
scala> val p = Person(name = "new person name")
p: Person = Person(new person name,no surname)
但是,由于您想明确知道一个值是否应该被默认,您可以在构造函数中实现基于 Map 的想法。如果您不想重复默认设置,这两个选项如何:
选项 1:默认值的外部化常量
在外部设置默认值。在主构造函数和基于 Map 的构造函数中都使用它们。
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")
选项 2:可选的替代构造函数
您可能会发现它更简洁一些,因为它不依赖于外部化的常量。这里唯一的缺点是,如果你想只用一些参数来构造,你必须把每个参数都包装在Some()
中。
case class Person(name: String, surname: String)
def this(name: Option[String] = None, surname: Option[String] = None) =
this(name.getOrElse("no name"), surname.getOrElse("no surname"))
def this(m: Map[String, String]) = this(m.get("name"), m.get("surname"))
用法:
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
【讨论】:
谢谢 dhg,我明白了,但我需要一个通用函数来加载可能不存在的值,我编辑了问题以澄清问题 @opensas,我现在明白了。我已经更新了两个可能是您正在寻找的选项。 很好的答案,我想我更喜欢第一种方法,在 Person 伴随对象中设置常量,只是为了让它们不那么外部...... +1 对于选项 #1。不过,我认为选项 #2 是Option
abuse。
+1 用于选项#1,创造性地使用带有 Map 参数的 alt 构造函数。 json 或 servlet 参数非常适合这里,谢谢【参考方案2】:
我认为这可能是 Either 的一个用例。您可以指定两种类型的 Either。
val name: Eiter[String, Unit] = Left("name")
val surname: Either[String, Unit] = Right( () )
现在你可以检查你是左还是右,并用你想要的参数调用构造函数。
【讨论】:
我试图避免使用每个可能存在/缺失的参数组合来调用构造函数......我不知道我是否关注了你......以上是关于Scala:如何使用默认值初始化对象的主要内容,如果未能解决你的问题,请参考以下文章