【问题标题】:Scala Map pattern matching issue [duplicate]Scala Map模式匹配问题[重复]
【发布时间】:2021-04-09 10:15:42
【问题描述】:

我是 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

据我所知,case (aKey, v) 中未使用 SomeLongNameObject 对象中的 aKey, 有没有办法强制它以比下面更优雅的方式使用对象 SomeLongNameObject 中的 val?

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

【问题讨论】:

    标签: scala dictionary design-patterns match


    【解决方案1】:

    当你写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, _) => ???
          ...
    

    【讨论】:

      猜你喜欢
      • 2014-09-30
      • 1970-01-01
      • 2014-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-06
      • 1970-01-01
      • 2018-09-23
      相关资源
      最近更新 更多