Erlang:在guard语句中匹配字符串

时间:2014-09-30 16:30:15

标签: string erlang string-matching

最近开始使用erlang并遇到上面的问题,你如何比较一个守护声明中的两个字符串?尝试了字符串:等于(x,y)方法,但无法让它在守卫内部工作。

3 个答案:

答案 0 :(得分:8)

你可以使用这样的模式匹配:

are_the_same(A, A) ->
  true;
are_the_same(_, _) ->
  false.

在第一个子句中,两个参数都被命名为A,这将导致它们相互模式匹配。或者确切地说,第一个参数将使用A运算符绑定到=变量,而第二个参数将使用A运算符绑定到=变量,但是A已受约束,它将被视为“比较”。您可以阅读more about this in docs

当然,你可以写一个写第一个clouse使用警卫像:

are_the_same(A, B) when A =:= B ->

答案 1 :(得分:4)

您不需要函数string:equal/2来比较字符串;您可以使用运营商===:=,这些运营商可以在警卫测试中使用。例如:

foo(A, B) when A =:= B ->
    equal;
foo(_, _) ->
    not_equal.

虽然在大多数情况下,您仍然希望使用模式匹配,如other answer中所述。

答案 2 :(得分:3)

由于Erlang调度的性质,您可以在警卫中使用的功能受到限制;特别是,Erlang旨在避免在保护语句中产生副作用(例如,调用另一个进程),因为保护程序由调度程序进行评估,并且不计入减少。这就是string:equal不起作用的原因。

话虽这么说,你可以使用Erlang的模式匹配来匹配字符串。请记住在Erlang中使用字符串作为列表,二进制文件或iolists(嵌套列表/二进制文件),并确保您正在测试/传递正确类型的字符串(iolists特别难以模式匹配并且是通常最好使用re模块处理,或通过iolist_to_binary将其转换为二进制文件。

例如,假设我们需要一个函数来测试字符串是否以" foo"开始:

bar("foo" ++ _Rest) -> true;
bar(<<"foo", Rest/binary>>) -> true;
bar(_Else) -> false.

如果您只是想测试特定的字符串,那就更容易了:

bar("foo") -> true;
bar(<<"foo">>) -> true;
bar(_Else) -> false.