首页 > 解决方案 > 二进制模式匹配和列表理解

问题描述

使用列表理解,elixir 允许像这样进行模式匹配:

iex()> for {a,2,c} = ch <- [{1,2,3},{4,5,6},3,4,5], do: c 
[3]

但是当我试图用二进制做类似的事情时,我失败了:

iex()> for  << b1::size(2), b2::size(3), b3::size(3) >> = <<ch>> <- 'hello', do: b1 
[]

尽管如此,它在独立时匹配得很好:

<< b1::size(2), b2::size(3), b3::size(3) >> = <<100>>
"d"
iex(282)> b2
4
iex(283)> b1
1
iex(284)> b3
4

当我将 matten 匹配子句作为 secornd 参数传递给for

iex(286)> for ch <- 'hello', << b1::size(2), b2::size(3), b3::size(3) >> = <<ch>>,  do: b1
[1, 1, 1, 1, 1]

如果可以用二进制做第一个例子,我很感兴趣。

标签: binarypattern-matchingelixirlist-comprehension

解决方案


这是失败的:

<<ch>> <- 'hello'

在你的第一个例子中,你做了var <- list,后来你尝试<<var>> <- list了,这无论如何都是不一样的。


'hello'首先是整数列表。检查这个:

[104,101,108,108,111]
#⇒ 'hello'

Kernel.SpecialForms.for/1正在逐一遍历列表。不能按原样将二进制与整数匹配:

<<_::size(2), _::size(3), _::size(3)>> = 101
#⇒ ** (MatchError) no match of right hand side value: 101

并且:

<<ch>> = 101
#⇒ ** (MatchError) no match of right hand side value: 101

您问题中的后一个代码示例有效,因为您匹配一个整数,然后明确告诉 Elixir/Erlang将其包装为二进制<< >>

<<b1::size(2), _::size(3), _::size(3)>> = <<101>>
#⇒ "e"

推荐阅读