This fails to compile:
Array[Byte](...) match { case Array(0xFE.toByte, 0xFF.toByte, tail @ _* ) => tail }
I can, however, compile this:
val FE = 0xFE.toByte
val FF = 0xFF.toByte
bytes match { Array( FE, FF, tail @ _* ) => tail }
Why does the first case fail to compile but not the second case?
Matching as currently implemented in Scala does not allow you to generate expressions inside your match statement: you must either have an expression or a match, but not both.
So, if you assign the values before you get into the match, all you have is a stable identifier, and the match works. But unlike almost everywhere else in Scala, you can't substitute an expression like
0xFE.toByte
for the valFE
.Type inference will work, so you could have written
since it knows from the type of
xs
that the literals-2
and-1
must be Byte values. But, otherwise, you often have to do just what you did: construct what you want to match to, and assign them to vals starting with an upper-case letter, and then use them in the match.There is no exceedingly good reason why it must have been this way (though one does have to solve the problem of when to do variable assignment and when to test for equality and when to do another level of unapply), but this is the way it (presently) is.