模式匹配Scala中列表的结尾/中间
发布时间:2020-12-16 18:58:04 所属栏目:安全 来源:网络整理
导读:有人可以给我一个更简单的解决方案,以下代码(在给定结构0xFC :: len :: payload :: … :: 0x0A :: 0x0D的情况下展开整数列表): object Payload { def unapply(z: List[Int]): Option[List[Int]] = if (z.length == z.head + 1) Some(z tail) else None}obje
有人可以给我一个更简单的解决方案,以下代码(在给定结构0xFC :: len :: payload :: … :: 0x0A :: 0x0D的情况下展开整数列表):
object Payload { def unapply(z: List[Int]): Option[List[Int]] = if (z.length == z.head + 1) Some(z tail) else None } object EndToken { def unapply(z: List[Int]): Option[List[Int]] = z.reverse match { case 0x0D :: 0x0A :: tail => Some(tail.reverse) case _ => None } } object Message { def unapply(z: List[Int]): Option[List[Int]] = z match { case 0xFC :: EndToken(x) => Some(x) case _ => None } } object Main extends App { val x = List(0xFC,0x03,0x01,0x02,0x0A,0x0D) x match { case Message(Payload(payload)) => println (payload) case _ => println("No match") } } 就像是: object Message { def unapply(z: List[Int]): Option[List[Int]] = z match { case 0xFC :: Payload(x) :: 0x0A :: 0x0D => Some(x) case _ => None } } 但是,当然,::期待元素,而不是列表,所以它不起作用…… 解决方法
这是我的解决方案(虽然重新阅读,我认为这就像丹尼尔的解决方案).它基于中缀操作模式,其中模式op(p,q)是相同的p op q.
运算符以:具有与::相同的前导,并以:结束于右边. (len,payload):!:tail与:!:((len,payload),tail)相同.基于长度的有效负载提取的实现有点复杂,但主要是因为我只想遍历列表一次. object :!: { type LengthPayload = (Int,List[Int]) // (len,payload) // returns ((len,unparsed) def unapply(z: List[Int]): Option[(LengthPayload,List[Int])] = { if (z == Nil) None else { val len = z.head // use ListBuffer to traverse the list only once val buf = collection.mutable.ListBuffer[Int]() def take(l: Int,list: List[Int]): Option[(LengthPayload,List[Int])] = { list match { case Nil if l > 0 => None case _ if l == 0 => Some((len,buf.toList),list) case _ => buf += list.head; take(l - 1,list.tail) } } take(len,z.tail) } } } 然后消息变得更简单(视觉上): object Message { def unapply(z: List[Int]): Option[List[Int]] = z match { case 0xFC :: (len,payload) :!: 0x0A :: 0x0D :: Nil => Some(payload) case _ => None } } 结果: val x = List(0xFC,0x0D) x match { case Message(payload) => println(payload) case _ => println("No match") } // List(1,2,3) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |