Scala最佳实践:简单的Option []用法

时间:2012-12-18 20:52:55

标签: scala null

作为Java-to-Scala切换器,我经常发现自己重写了像

这样的空处理
val itemOpt: Option[Item] = items.get(coords) // "items" is something like a Map
if (itemOpt.isDefined) {
  val item = itemOpt.get
  // do something with item, querying item fields a lot of times, for example
  if (item.qty > 10) {
    storeInVault(item.name, item.qty, coords)
  } else {
    storeInRoom(item)
  }
}

我觉得它看起来很丑陋而真的看起来像是从Java重写的一段代码:

Item item = items.get(coords);
if (item != null) {
  // do something with item, querying item fields a lot of times, for example
}

它在Java中看起来也很难看,但至少它只有一行。在Scala中处理这种简单案例的最佳做法是什么?我已经知道flatMapflatten来处理Option[Stuff]的集合,我知道getOrElse来处理默认值。我梦想着像:

items.get(coords).doIfDefined(item =>
  // do stuff with item
)

但我在Option API中没有看到类似内容。

4 个答案:

答案 0 :(得分:12)

非常受欢迎的使用模式:

val item: Option[Int] = None
val result = item map (_ + 1) getOrElse 0

所以你只需使用map来转换价值(如果已定义)。

如果您只想使用存储在Option内的值,那么只需使用foreach

item foreach { it =>
    println(it)
}

如您所见,Option也支持许多集合方法,因此您实际上不需要学习新的API。您可以将其视为具有1或0元素的集合。

答案 1 :(得分:7)

这应该可以实现您的目标:

items.get(coords).foreach{ item => 
  //do stuff
}

答案 2 :(得分:5)

检查这个Tony Morris post。当我试图了解Option时,它对我非常有帮助。您的代码可能会以这样的方式重写:

for (item <- items.get(coords)) { // "items" is something like a Map
  // do something with item, querying item fields a lot of times, for example
  if (item.qty > 10) {
    storeInVault(item.name, item.qty, coords)
  } else {
    storeInRoom(item)
  }
}

答案 3 :(得分:3)

此外,Option可用于if后卫的模式匹配。我个人喜欢在这种情况下使用它,并认为它更容易阅读。

因为选项上的map仅在选项不是None时生效,所以您可以先执行此操作,然后使用模式匹配检查您的itemOpt是否为{{ 1}}或Some

None