Scala - 优雅的地图查找失败

Scala - graceful map lookup failure

假设我想要一个 Map,如果我无法在其中查找某个值,应该会触发整个过程的中止。

例如(简化):

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 返回与错误无关的默认值。

但是,我严重怀疑这是一个建议的做法。

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

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-comprehension(或使用 map 和 [= 的脱糖版本)重写它17=] 与 myMap.get).