2014-09-30 2 views
1

Начал работать с erlang совсем недавно и столкнулся с проблемой выше, как вы собираетесь сравнивать две строки в инструкции охраны? Пробовал строку: equal (x, y), но не смог заставить ее работать внутри охранника.Erlang: Соответствующие строки в инструкции охраны

ответ

4

Вам не нужна функция string:equal/2 для сравнения строк; вы можете использовать операторы == или =:=, которые разрешены при проведении проверочных испытаний. Например:

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

Хотя в большинстве случаев вы хотели бы использовать вместо сопоставления картины, как описано в other answer.

+0

Oh, "=: =" сделал чудеса. большое спасибо! –

3

Функции, которые вы можете использовать в охранниках, ограничены из-за характера планирования Erlang; в частности, Erlang стремится избегать побочных эффектов в защитных утверждениях (например, призывая к другому процессу), потому что охранники оцениваются планировщиком и не учитывают сокращения. Вот почему string:equal не работает.

Как сказано, вы можете использовать сопоставление образцов Erlang для соответствия строкам. Имейте в виду использование строк в виде списков, двоичных файлов или iolists (вложенных списков/двоичных файлов) в Erlang и убедитесь, что вы тестируете/передаете строки правильного типа (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. 
+0

@legoscia ответы решить, но если вы не возражаете: Как бы вы модель соответствует переменной с другой переменной с помощью этого метод? и что именно делает выражение <<_, _>>? –

+1

К сожалению, одно из ограничений сопоставления шаблонов - это то, что вы описываете: вы не можете сопоставить другую переменную со списком или двоичным кодом (например, ни 'bar (Test ++ _Rest, Test)', ни 'bar (<< Test/binary, _Rest/binary >>, Test) 'будет работать). Решение @ legoscia лучше всего подходит для сопоставления всех переменных. Если вы ищете частичные совпадения, вам придется привязать переменную, которую вы тестируете в объявлении функции, и использовать аргумент case для утверждения соответствия. –

+1

И <<_,_>>, если я ошибаюсь, соответствует двухбайтовому двоичному. –

7

Вы можете использовать шаблон согласования, как это:

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

В первом предложении оба аргумента названы A, что приведет к их быть картина соответствует друг против друга. Или, точнее, первый аргумент будет связываться с переменной A с использованием оператора =, а второй аргумент будет связываться с переменной A с оператором =, но поскольку A связан уже, он будет рассматриваться как «сравнение». Вы можете прочитать more about this in docs.

И, конечно, вы могли бы написать написать первый Клаусом с использованием настороже, как:

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