模式匹配和二进制列表理解

时间:2018-04-24 11:47:40

标签: binary pattern-matching elixir list-comprehension

使用列表理解,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

当我将mattern匹配子句作为secornd参数传递给for时,它也很有效:

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

我感兴趣的是,是否有可能像二元的第一个例子那样做。

1 个答案:

答案 0 :(得分:1)

这是失败的:

<<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"