Erlang.Как переназначить значение в строку - PullRequest
0 голосов
/ 06 февраля 2019

Я новичок в Эрланге.Я просто хочу переназначить значение строковой переменной:

get_alert_body(Packet) ->
    BodyElement = element(8,Packet),
    Body = "my text",
    Els = xmpp:get_els(Packet),
    lists:foreach(fun(El) ->
        ElementName = io_lib:format("~s",[xmpp:get_name(El)]),
        IsFile = string:equal(ElementName,"fileType"),
        if
            IsFile ->
                FileType = fxml:get_tag_cdata(El),
                IsPhoto = string:equal(FileType,"photo"),
                IsVideo = string:equal(FileType,"video"),
                if
                    IsPhoto ->
                        %% if it gets to this I would like to return "my photo"
                        Body = "my photo";
                    IsVideo ->
                        %% else if it gets to this I would like to return "my video"
                        Body = "my video";
                    true ->
                        %% otherwise I would like to return "my text"
                        ok
                end;
            true ->
                ok
        end
    end, Els),
    Body.

Но я получаю эту ошибку:

error,{badmatch,"test2"}

Даже если я сделаю что-то вроде:

A = "test1",
A = "test2",

Я получаю ту же ошибку.

Буду признателен за вашу помощь.

Ответы [ 2 ]

0 голосов
/ 07 февраля 2019

= не является оператором присваивания в эрланге, скорее это оператор сопоставления с шаблоном .

Если вы напишите:

{A, hello} = {10, hello}.

и A не был привязан к (или вы можете сказать назначил ) значение еще, затем erlang пытается создать совпадение для правой части (потому что = является оператором сопоставления).Чтобы создать совпадение для правой стороны, erlang связывает / присваивает A значение 10 (для интереса вы можете предположить, что *&* является оператором присваивания в erlang, поэтому erlang делает A *&* 10, чтобы присвоить 10 переменной A).

Это работает так же, если вы напишите:

B = 10,

Чтобы erlang создал совпадение для правой стороны, erlang присваивает B значение 10: B *&* 10, и совпадение успешно, поэтому выполнение продолжается на следующей строке.Однако если вы напишите:

C = 3,
C = 22,

, то в первой строке erlang присваивает значение 3 C: C *&* 3, чтобы найти совпадение для правой части (потому что =является оператором матча).Но вторая строка эквивалентна:

3 = 22,

И в сообщении об ошибке будет сказано, что оператор сопоставления = завершился неудачно, поскольку нет никакого способа сделать так, чтобы левая часть соответствовала правой стороне 22.

0 голосов
/ 06 февраля 2019

Вы не можете.Erlang имеет функцию, называемую «одиночное присваивание», что означает, что вы не можете изменить значение переменной после ее назначения в первый раз.Если вы попытаетесь это сделать, то вместо этого он станет совпадением с шаблоном, и вы получите ошибку badmatch, как если бы вы попытались сделать "test1" = "test2".

Ваш пример можно записать так:

A =
  if
      Condition ->
          "test2";
      true ->
          "test1"
  end

См. этот вопрос и его ответы для получения дополнительной информации об одном задании.


В вашем расширенном примере то, что вы пытаетесь сделать, может быть достигнуто с помощью сгиба,То есть, учитывая список и дополнительное значение, называемое «аккумулятор», просмотрите список и вызовите функцию для каждого элемента, и пусть возвращаемое значение этой функции будет новым аккумулятором - и в конце вернет аккумулятор.

Используйте для этого lists:foldl/3, например:

get_alert_body(Packet) ->
    BodyElement = element(8,Packet),
    DefaultBody = "my text",
    Els = xmpp:get_els(Packet),
    lists:foldl(fun(El, Body) ->
        ElementName = io_lib:format("~s",[xmpp:get_name(El)]),
        IsFile = string:equal(ElementName,"fileType"),
        if
            IsFile ->
                FileType = fxml:get_tag_cdata(El),
                IsPhoto = string:equal(FileType,"photo"),
                IsVideo = string:equal(FileType,"video"),
                if
                    IsPhoto ->
                        %% if it gets to this I would like to return "my photo"
                        "my photo";
                    IsVideo ->
                        %% else if it gets to this I would like to return "my video"
                        "my video";
                    true ->
                        %% otherwise return the existing value
                        Body
                end;
            true ->
                ok
        end
    end, DefaultBody, Els).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...