Scala - 优雅的地图查找失败

时间:2015-07-07 14:35:11

标签: scala dictionary return arguments default-value

让我们说我想要一张地图,如果我没有查找某个值,就应该触发整个程序的中止。

E.g。 (简化的):

def myMethod = {
    val res = foo(Map[String,String](("hello" -> "Hello")),false)
    if(!res) println("World!")
}

def foo(myMap:Map[String,String],myDefault:Boolean):Boolean = {
    val actualDefault = baz(myDefault)
    val m = myMap.withDefault{
        case _ => return actualDefault
    }
    bar((s:String) => m(s))
    return true
}

def bar(lookup:String => String):Unit = {
    print(lookup("hello") + " ")
    println(lookup("world"))
}

def baz(myDefault:Boolean):Boolean = false

在我的情况下,这种行为是完美的,其中barfoo多次调用,并且任何一次调用中的单个错误都会导致foo' s返回与错误无关的默认值。

但是,我怀疑这是建议的做法。

是否有替代(更好)的方法来实现这一目标?

1 个答案:

答案 0 :(得分:2)

Option monad中执行地图查找更加惯用。这允许您在失败后停止后续查找,并提供默认值。例如,如果我们有这张地图:

val myMap = Map("foo" -> "bar", "hello" -> "world", "a" -> "b")

我们可以这样写:

val result: String = (
  for {
    f <- myMap.get("foo")
    h <- myMap.get("hello")
    a <- myMap.get("a")
  } yield s"$f $h $a"
).getOrElse("my default")

我们会得到"bar world b"。如果我们试图查找地图中不存在的密钥,我们将获得默认值:

scala> val result: String = (
     |   for {
     |     f <- myMap.get("foo")
     |     x <- myMap.get("x")
     |     h <- myMap.get("hello")
     |     a <- myMap.get("a")
     |   } yield s"$f $x $h $a"
     | ).getOrElse("my default")
result: String = my default

我不确定我是否理解您的确切用例,但您应该能够使用for - 理解(或使用map和{{1}的desugared版本)重写它与flatMap)。