2017-01-10 74 views
2

为什么此代码以这种方式工作?有没有一种方法可以用这种方式使用bar完成我想要的? (我知道有替代品做模式相匹配的字符串)串联匹配的字符串插值

# Elixir 1.3.4 
defmodule MyMod do 

    @foo "abc" 

    def concatenation_operator_with_interpolation do 
    bar = "abc" 

    "#{@foo}::" <> matchworks = "abc::xyz" 
    IO.puts matchworks # xzy 

    "#{bar}::" <> matchbroke = "abc::xyz" # cannot invoke remote function String.Chars.to_string/1 inside match 
    IO.puts matchbroke # never runs 
    end 

end 

MyMod.concatenation_operator_with_interpolation 
+0

必须与字符串插值有关。我可以用'“#{bar}”=“abc”'重现这一点。 –

+1

'bar =“abc”; size = byte_size(bar); <<^bar :: binary-size(size)>><> matchworks =“abc :: xyz”' – Dogbert

+0

是的,我想知道是否有什么我可以做的插补工作。以上内容不太简洁......你知道吗? –

回答

6

简短的回答:你需要存储的bar的大小,然后做<<^bar::binary-size(size)>> <> matchworks = "abc::xyz"

iex(1)> bar = "abc" 
"abc" 
iex(2)> size = byte_size(bar) 
3 
iex(3)> <<^bar::binary-size(size)>> <> matchworks = "abc::xyz" 
"abc::xyz" 
iex(4)> matchworks 
"::xyz" 
iex(5)> <<^bar::binary-size(size)>> <> matchworks = "ab::xyz" 
** (MatchError) no match of right hand side value: "ab::xyz" 

龙答:二进制匹配涉及串联的情况下,除LHS上最后一个以外的所有二进制文件必须是编译时已知的常量值或具有明确的大小值。

在第一种情况下(它适用于你),Elixir在编译时计算插值,因为里面的所有表达式都是编译时间常量,并且用类似"abc" <> matchworks = "abc::xyz"的东西代替它,它工作正常。

在第二种情况下,bar是一个变量,因此"#{bar}"可以在运行时具有任何值,因此您需要明确指定大小。

+0

谢谢!你的描述为什么恒定的作品是非常有意义的。 –