简单案例类:
case class country(name: String, townPopulation: Map[String,Int])
用简单的例子:
scala> val germany = country("Germany",Map("Berlin" -> 100000, "Saale" -> 4000))
germany: country = country(Germany,Map(Berlin -> 100000, Saale -> 4000))
scala> germany.townPopulation("Berlin")
res77: Int = 100000
scala> germany.townPopulation("blergh")
java.util.NoSuchElementException: key not found: blergh
at scala.collection.MapLike$class.default(MapLike.scala:228)
at scala.collection.AbstractMap.default(Map.scala:59)
at scala.collection.MapLike$class.apply(MapLike.scala:141)
at scala.collection.AbstractMap.apply(Map.scala:59)
... 42 elided
我想为不存在的城镇返回0,这可以在声明val时完成:
scala> val germany = country("Germany",Map("Berlin" -> 100000, "Saale" -> 4000).withDefaultValue(0))
germany: country = country(Germany,Map(Berlin -> 100000, Saale -> 4000))
scala> germany.townPopulation("fdhjkjhkhjdfg")
res79: Int = 0
但是我无法弄清楚如何在一个地方做到这一点,至少在它是一个案例类时,我想要一些简单的事情,但我显然做错了:
scala> case class country(name: String, townPopulation: Map[String,Int].withDefaultValue(0))
<console>:1: error: ')' expected but '.' found.
case class country(name: String, townPopulation: Map[String,Int].withDefaultValue(0))
^
<console>:1: error: ';' expected but ')' found.
case class country(name: String, townPopulation: Map[String,Int].withDefaultValue(0))
是否有一个简短的简单路径到一个总是0作为defaultValue的解决方案?
答案 0 :(得分:2)
我看到几种可能的方式:
添加封装默认值逻辑的辅助方法
def population(town : String) : Int = townPopulation.getOrElse(town, 0)
将方法添加到具有相同目的的伴随对象
def withDefault(name: String, townPopulation: Map[String, Int]) : country =
country(name, townPopulation.withDefaultValue(0))
答案 1 :(得分:1)
使用map.get(),它返回Option
:
println germany.townPopulation.get("blergh").getOrElse(0)
// or, more concisely:
println germany.townPopulation.getOrElse("blergh", 0)
啊,在重新阅读你的问题时,你想要硬编码案例类中的默认值。我想你将不得不混淆apply()方法。
答案 2 :(得分:0)
val germany = country("Germany",
Map("Berlin" -> 100000, "Saale" -> 4000)
.withDefaultValue(0))
编辑(在OP的回答之后):
我的坏!应该仔细阅读你的问题。
如this SO question中所述:您无法选择更改默认构造函数存储其参数的方式(例如,在将参数存储为val之前修改参数)[...]
另一种解决方案是声明常规class
及其随播广告对象:
class Country(val name: String, val townPopulation: Map[String, Int])
case object Country {
def apply(name: String, townPopulation: Map[String, Int]) =
new Country(name, townPopulation.withDefaultValue(0))
}
这将允许您使用漂亮的语法声明国家/地区:
val germany = Country("Germany", Map("Berlin" -> 100000, "Saale" -> 4000))
assert(germany.townPopulation("Berlin") == 100000)
assert(germany.townPopulation("Blergh") == 0)
但请注意,由于不一个case class
,您无法获得通常的case class
特权,例如:
// Compiler will give you
// "object Country is not a case class,
// nor does it have an unapply/unapplySeq member"
//germany match {
// case Country(a, b) => println("It won't compile! Not a case class")
//}
根据您的使用情况,您可以走很长的路,并实施方法unapply
和unapplySeq
,以便在需要时检索此类行为!