Scala 在case类中使用defaultvalue

Scala 在case类中使用defaultvalue,scala,dictionary,case-class,Scala,Dictionary,Case Class,简单案例类: 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)

简单案例类:

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))
scala>case类国家(名称:String,城镇人口:Map[String,Int].withDefaultValue(0))
:1:错误:')应为“”,但找到“”。
案例类国家(名称:String,城镇人口:Map[String,Int].withDefaultValue(0))
^
:1:错误:';'应为“”,但找到“”。
案例类国家(名称:String,城镇人口:Map[String,Int].withDefaultValue(0))
是否有一个短的简单路径指向始终使用0作为默认值的解决方案?

使用map.get(),它返回一个
选项:

println germany.townPopulation.get("blergh").getOrElse(0)
// or, more concisely:
println germany.townPopulation.getOrElse("blergh", 0)
啊,在重读你的问题时,你想在case类中硬编码默认值。我想您将不得不处理apply()方法。

使用map.get(),它返回一个
选项

println germany.townPopulation.get("blergh").getOrElse(0)
// or, more concisely:
println germany.townPopulation.getOrElse("blergh", 0)
啊,在重读你的问题时,你想在case类中硬编码默认值。我想您必须处理apply()方法


编辑(在OP的回答之后):

我的错!你应该把你的问题读得更透彻些

如中所述:您无权更改默认构造函数存储其参数的方式(例如,在将参数存储为VAL之前修改参数)[…]

另一种解决方案是声明一个常规的
及其伴随对象:

这将允许您使用nice语法声明国家:

val germany = Country("Germany", Map("Berlin" -> 100000, "Saale" -> 4000))
assert(germany.townPopulation("Berlin") == 100000)
assert(germany.townPopulation("Blergh") == 0)
但请注意,由于它不是一个
案例类
,因此您不会获得通常的
案例类
特权,例如:

// 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
unplyseq
,以便在需要时检索此类行为


编辑(在OP的回答之后):

我的错!你应该把你的问题读得更透彻些

如中所述:您无权更改默认构造函数存储其参数的方式(例如,在将参数存储为VAL之前修改参数)[…]

另一种解决方案是声明一个常规的
及其伴随对象:

这将允许您使用nice语法声明国家:

val germany = Country("Germany", Map("Berlin" -> 100000, "Saale" -> 4000))
assert(germany.townPopulation("Berlin") == 100000)
assert(germany.townPopulation("Blergh") == 0)
但请注意,由于它不是一个
案例类
,因此您不会获得通常的
案例类
特权,例如:

// 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
unplyseq
,以便在需要时检索此类行为

我认为有几种可能的方法:

  • 添加封装默认值逻辑的辅助方法

    def population(town:String):Int=townPopulation.getOrElse(town,0)

  • 将方法添加到具有相同目的的伴随对象

    def with default(名称:String,城镇人口:Map[String,Int]):country=
    国家(名称,城镇人口。默认值为(0))
    


    • 我认为有几种可能的方法:

      • 添加封装默认值逻辑的辅助方法

        def population(town:String):Int=townPopulation.getOrElse(town,0)

      • 将方法添加到具有相同目的的伴随对象

        def with default(名称:String,城镇人口:Map[String,Int]):country=
        国家(名称,城镇人口。默认值为(0))
        


      Map.getOrElse
      看起来更好imo
      Map.getOrElse
      看起来更好我有一个在里面,它做到了,但是你每次都必须使用defaultvalue,我更愿意直接在case类中声明它,以后再也不用担心它了好吧,这不是我所希望的简单的神奇解决方案,但是谢谢你解释为什么不:)我有一个在那里,它做到了,但是你每次都必须使用DefaultValue,我更愿意直接在case类中声明它,以后再也不用担心它了,这不是我所希望的简单的魔法解决方案,但感谢您解释为什么不:)只要阅读回答值==人口,似乎“拥有人口,即给定城市/城镇存在一个密钥”和地图中根本不存在之间存在差异。使用
      0
      ,这种区别将丢失。也许
      Option[Int]
      不适合地图键值对中的值?仅阅读值==人口的回答,似乎“有人口,即给定城市/城镇存在一个键值”与地图中根本不存在之间存在差异。使用
      0
      ,这种区别将丢失。也许
      选项[Int]
      不适合映射的键值对中的值?