【问题标题】:Scala extractors: a cumbersome exampleScala 提取器:一个麻烦的例子
【发布时间】:2013-11-20 00:29:22
【问题描述】:

一切都从几个考虑开始:

  • 提取器是 Scala 对象,它实现了一些具有某些特性的 unapply 方法(直接来自 «Programming in Scala 2nd edition»,我已经检查过)
  • 对象是在静态范围内延迟初始化的单例

我试图以案例类的形式实现一种“参数提取器”,以尝试为 SHA1 检查提供一种优雅的模式。

我想根据缓冲区检查 SHA1 列表,以匹配它们中的哪一个适用。我想写这样的东西:

val sha1: Array[Byte] = ...
val sha2: Array[Byte] = ...

buffer match {
  case SHA1(sha1) => ...
  case SHA1(sha2) => ...
  ...
}

好的,看起来很奇怪,但现在不要打扰。

我试图通过简单地实现这样的案例类来解决问题

case class SHA1(sha1: Array[Byte]) {
  def unapply(buffer: Array[Byte]): Boolean = ...
}

并像使用它一样使用它

case SHA1(sha1)() =>

甚至

case (SHA1(sha1)) =>

但它不起作用:编译器失败。

然后我稍微改了一下代码:

val sha1 = SHA1(sha1)
val sha2 = SHA1(sha2)
buffer match {
  case sha1() => println("sha1 Match")
  case sha2() => println("sha2 Match")
  ...
}

它可以正常工作。

问题是:

Q1:使用这种«提取器»有什么微妙的含义

Q2:如果最后一个示例有效,我应该使用哪种语法来避免定义临时的vals? (如果任何提供的编译器的工作与匹配...case 表达式)


编辑 Aaron 提出的解决方案也不起作用。一个sn-p:

case class SHA1(sha1: Array[Byte]) { 
  def unapply(buffer: Array[Byte]) = buffer.length % 2 == 0
}

object Sha1Sample {
  def main(args: Array[String]) {
    println("Sha1 Sample")

    val b1: Array[Byte] = Array(0, 1, 2)
    val b2: Array[Byte] = Array(0, 1, 2, 3)
    val sha1 = SHA1(b1)
    List(b1, b2) map { b =>
      b match {
        case sha1() => println("Match") // works
        case `sha1` => println("Match") // compile but it is semantically incorrect
        case SHA1(`b1`) => println("SOLVED")  // won't compile
        case _ => println("Doesn't Match")
      }
    }
  }
}

【问题讨论】:

  • 我不确定你到底想要完成什么。
  • 实际上我应该考虑删除这篇文章。如果正则表达式以相同的方式工作,A1 应该是“否”,而 Q2 应该与编译器施加的一些约束有关……

标签: scala extractor


【解决方案1】:

简短回答:如果您不希望将小写标识符解释为模式变量,则需要在小写标识符周围加上反引号。

case Sha1(`sha1`) => // ...

this question

【讨论】:

  • 好像也没用。请查看我编辑的帖子。谢谢。
  • 啊,我明白了。我误解了你的用例。编译器期待您的 SHA1 出现的模式提取器,所以是的,您需要将 SHA1 应用于匹配表达式之外的特定哈希。
猜你喜欢
  • 2011-11-22
  • 1970-01-01
  • 2012-08-25
  • 2023-02-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-04
  • 1970-01-01
相关资源
最近更新 更多