Начал работать с erlang совсем недавно и столкнулся с проблемой выше, как вы собираетесь сравнивать две строки в инструкции охраны? Пробовал строку: equal (x, y), но не смог заставить ее работать внутри охранника.Erlang: Соответствующие строки в инструкции охраны
ответ
Вам не нужна функция string:equal/2
для сравнения строк; вы можете использовать операторы ==
или =:=
, которые разрешены при проведении проверочных испытаний. Например:
foo(A, B) when A =:= B ->
equal;
foo(_, _) ->
not_equal.
Хотя в большинстве случаев вы хотели бы использовать вместо сопоставления картины, как описано в other answer.
Функции, которые вы можете использовать в охранниках, ограничены из-за характера планирования 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.
@legoscia ответы решить, но если вы не возражаете: Как бы вы модель соответствует переменной с другой переменной с помощью этого метод? и что именно делает выражение <<_, _>>? –
К сожалению, одно из ограничений сопоставления шаблонов - это то, что вы описываете: вы не можете сопоставить другую переменную со списком или двоичным кодом (например, ни 'bar (Test ++ _Rest, Test)', ни 'bar (<< Test/binary, _Rest/binary >>, Test) 'будет работать). Решение @ legoscia лучше всего подходит для сопоставления всех переменных. Если вы ищете частичные совпадения, вам придется привязать переменную, которую вы тестируете в объявлении функции, и использовать аргумент case для утверждения соответствия. –
И <<_,_>>, если я ошибаюсь, соответствует двухбайтовому двоичному. –
Вы можете использовать шаблон согласования, как это:
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 ->
Oh, "=: =" сделал чудеса. большое спасибо! –