为什么这段代码以这种方式工作?有没有办法用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
Dogbert.. 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}"
可以在运行时具有任何值,因此您需要明确指定大小.
简短的回答:你需要存储大小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}"
可以在运行时具有任何值,因此您需要明确指定大小.