Scala Map模式匹配问题

Scala Map pattern matching issue

我是 Scala 新手,

对于映射中的每个键,我想匹配一个新值

class SomeLongNameObject {
    val m: Map[String, String] = Map("a" -> "aa",
      "b" -> "bb",
      "other" -> "someString")

    m.map {
      case (aKey, v) => println("a found")
      case (bKey, v) => println("b found")
      case (k,v) => println("fallback")
    }
  }

  object SomeLongNameObject {
    val aKey = "a"
    val bKey = "b"
  }
  val someObject = new SomeLongNameObject

我希望(并希望)打印给定的地图

a found

b found

fallback

然而,结果是

a found

a found

a found

据我了解 aKey 来自 case (aKey, v) 中未使用的 SomeLongNameObject 对象, 有没有一种方法可以强制它以比下面更优雅的方式使用对象 SomeLongNameObject 中的值?

m.map {
      case (SomeLongNameObject.aKey, v) => println("a found")
      case (SomeLongNameObject.bKey, v) => println("b found")
      case (k,v) => println("fallback")
    }

当你写 case (aKey, v) => ... 时,意思是“解构元组,并将第一个元素分配给局部变量 aKey,将第二个元素分配给局部变量 b。它确实不管具有相同名称的变量是否已经在范围内(在您的情况下它们实际上不在范围内,您需要 import SomeLongNameObject._ 将它们引入)

告诉编译器您实际上是在谈论匹配变量值而不仅仅是赋值的一种方法是使用反引号:

    case (`aKey`, v) => ???
如果 aKey 在范围内,

会起作用。

另一种方法是利用“秘密功能”:如果变量名以大写字母开头,则不需要反引号 :) 如果不是 aKey,您只需要 A,这会起作用:case (A, v) => ???

另一种方法是使用保护条件:

   case (k,v) if k == aKey => ???

最后,您自己找到的解决方案:case (SomeLongNameObject.aKey, v) => 其实很好。我个人宁愿坚持这种方法,只需将对象的名称更改为有意义但简短的名称(我可能会这样做 - 我非常讨厌长名称),或者至少使用别名:

   val keys = SomeLongNameObject
   foo foreach { 
      case (keys.aKey, _) => ???
      ...