首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >Scala:如何使用默认值初始化对象

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

Stack Overflow用户
提问于 2012-05-07 01:44:31
回答 2查看 26.8K关注 0票数 14

我认为用一个例子来解释这一点会更好。

我有以下案例类

代码语言:javascript
代码运行次数:0
运行
复制
case class Person(name: String = "no name", surname: String = "no surname")

并且我想创建一个通用函数来填充它,例如,json消息,它可能不指定所有字段。

我知道,要使用默认值,简单的答案是不将它们传递给构造函数,但是如果我有几个字段可能出现在json中,也可能没有出现在json中,我应该使用一个巨大的switch语句来涵盖所有可能的缺少参数的组合。在这种情况下,在读完json之后,我应该注意名字和姓氏的存在,没有名字,没有姓氏,没有名字也没有姓氏大小写…(天哪,我希望我说得很清楚)。

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

代码语言:javascript
代码运行次数:0
运行
复制
{ "name": "john", "surname": "doe" }
{ "surname": "doe" }
{ "name": "john" }
{ }

这就是为什么我在寻找一种更通用的方法来处理这个问题。

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

我在想像这样的东西:

代码语言:javascript
代码运行次数:0
运行
复制
val p = Person(name= "new person name", surname= Unit)

在这种情况下,surname应该获取默认值

或者类似于

代码语言:javascript
代码运行次数:0
运行
复制
val p = Person( Map( "name" -> "new person name" ) _* )

因此,它还接受surname的默认值

或者在构造函数中这样做,如果我检测到一个空值(或无),我可以赋值为默认值。

实际上,我正在尝试避免重复默认值的定义。

无论如何,实现这一目标最常用的方法是什么?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-05-07 01:47:05

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

代码语言:javascript
代码运行次数:0
运行
复制
scala> val p = Person(name = "new person name")
p: Person = Person(new person name,no surname)

但是,由于您希望显式地知道某个值是否应为默认值,因此可以在构造函数中实现基于Map的想法。如果你不想重复默认设置,下面这两个选项如何:

选项1:默认值的外部化常量

在外部设置默认值。在主构造函数和基于Map的构造函数中都使用它们。

代码语言:javascript
代码运行次数:0
运行
复制
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))
}

用法:

代码语言:javascript
代码运行次数:0
运行
复制
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()中。

代码语言:javascript
代码运行次数:0
运行
复制
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"))
}

用法:

代码语言:javascript
代码运行次数:0
运行
复制
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
票数 23
EN

Stack Overflow用户

发布于 2012-05-07 02:58:40

我认为这对任何一个都可能是一个有用的案例。您可以指定具有两种类型的。

代码语言:javascript
代码运行次数:0
运行
复制
val name: Eiter[String, Unit] = Left("name")
val surname: Either[String, Unit] = Right( () )

现在,您可以检查是否拥有Left或Right,并使用所需的参数调用构造函数。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10472758

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档