模式匹配字节数组

Pattern Matching Array of Bytes

编译失败:

Array[Byte](...) match { case Array(0xFE.toByte, 0xFF.toByte, tail @ _* ) => tail }

但是我可以编译这个:

val FE = 0xFE.toByte
val FF = 0xFF.toByte 
bytes match { Array( FE, FF, tail @ _* ) => tail }

为什么第一种情况编译失败,第二种情况编译不通过?

因为你在match中看到的不是构造函数而是extractor。提取器将数据提取到提供的变量中。这就是第二种情况起作用的原因——您在那里提供变量。顺便说一下,您不必提前创建它们。

有关提取器的更多信息,请访问 http://docs.scala-lang.org/tutorials/tour/extractor-objects.html

当前在 Scala 中实现的匹配不允许您在匹配语句中生成表达式:您必须 或者 有一个表达式 匹配,但不能同时匹配。

因此,如果您在进入匹配之前分配值,您所拥有的只是一个稳定的标识符,并且匹配有效。但与 Scala 中几乎所有其他地方不同的是,您 不能 将表达式 0xFE.toByte 替换为 val FE.

类型推断会起作用,所以你可以这样写

xs match { case Array(-2, -1, tail) => tail }

因为它从 xs 的类型知道文字 -2-1 必须是字节值。但是,除此之外,您通常必须做您所做的事情:构造您想要匹配的内容,并将它们分配给以大写字母开头的 vals,然后在匹配中使用它们。

没有很好的理由说明它必须是这样的(尽管确实必须解决何时进行变量赋值以及何时测试相等性和什么时候进行另一级取消应用),但这就是它(目前)的方式。