是否可以在scala的akka​​ ByteString上进行模式匹配?

时间:2016-07-11 04:51:08

标签: scala pattern-matching akka

我使用akka's tcp extention

实现自定义TCP协议

在tcp服务器示例here

中采用SimplisticHandler
class SimplisticHandler extends Actor {
  import Tcp._
  def receive = {
    case Received(data) => sender() ! Write(data)
    case PeerClosed     => context stop self
  }
}

Received(data)下,是否可以在字节序列上进行模式匹配?据我了解,需要定义一个提取器才能使模式匹配起作用。根据{{​​3}}似乎没有定义unapply

我想要类似的东西:

def receive = {
    case Received(data) =>
        val worker = getSomeWorkerActor
        worker ! data
  }

然后是儿童工作者:

private[this] def commandA(cmd: ByteString) = println(cmd)
def receive = {
    // [warn] foo.scala:55: abstract type pattern Coll is unchecked since it is eliminated by erasure
    // [error] foo.scala:55: type mismatch;
    // [error]  found   : scala.collection.SeqLike[T,Coll]
    // [error]  required: akka.util.ByteString
    case 0x01 +: command => commandA(command)  
    case 0x02 +: 0x03 +: command => commandB(command)
}

同时将command保持为ByteString。如果是这样的话?或者什么是推荐的替代品? 我希望避免解码为String然后与字符串进行比较,如果可能的话。

scala 2.11.8,akka 2.4.7

1 个答案:

答案 0 :(得分:3)

在模式匹配结构中,模式的类型不是从case子句的右侧进行的,另请参阅Pattern Matching Expressions。因此,不考虑commandAcommandB的参数类型。你必须先在ByteString上匹配:

def receive = {
  case b: ByteString => b match {
    case 0x01 +: command => commandA(command)  
    case 0x02 +: 0x03 +: command => commandB(command)
  }
}