二郎如何将值重新分配给字符串

时间:2019-02-06 15:00:46

标签: string erlang

我是Erlang的新手。我只想将值重新分配给字符串变量:

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",

我遇到同样的错误。

感谢您的帮助。

3 个答案:

答案 0 :(得分:6)

不能。 Erlang具有称为“单一分配”的功能,这意味着您在首次分配变量后就无法更改其值。如果尝试执行此操作,它将变成模式匹配,并且会收到badmatch错误,就像尝试执行"test1" = "test2"一样。

您的示例可以写为:

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

有关单项作业的更多信息,请参见this question及其答案。


在您的扩展示例中,您想要做的事情可以轻松实现。也就是说,给定一个列表和一个称为“累加器”的附加值,遍历该列表并为每个元素调用一个函数,然后将该函数的返回值作为新的累加器-最后返回累加器。 / p>

为此使用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).

答案 1 :(得分:1)

=不是erlang中的赋值运算符,而是 pattern match 运算符。

如果您写:

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

A尚未绑定到 (或者您可以说 assigned )一个值,然后erlang尝试为右手创建匹配项边(因为=是匹配运算符)。要为右侧创建匹配项,erlang会将值A绑定/赋值为10(为方便起见,您可以假设*&*是erlang中的赋值运算符,因此erlang进行A *&* 10来将10赋给变量A)。

如果您这样写,它的工作方式相同:

B = 10,

为了使erlang为右侧创建匹配项,erlang为B赋值10B *&* 10,匹配成功,因此执行在下一行继续。但是,如果您写:

C = 3,
C = 22,

然后在第一行中,erlang将值3分配给CC *&* 3以找到右侧的匹配项(因为=是匹配运算符)。但是第二行等效于:

3 = 22,

错误消息将指出匹配运算符=失败,因为没有办法使左侧匹配右侧22

答案 2 :(得分:0)

Erlang 中的变量不能重新赋值,但可以通过 "shadowed" 来达到类似的效果。在此示例中,变量 X 在匿名函数的范围内被“重新定义”为 X ++ Y

-module(main).
-export([main/1]).

main([_]) ->
    X = "X",
    Y = "Y",
    fun(X) -> io:fwrite(X) end(X++Y),
    init:stop().

该程序打印 XY 而不是 X,因为 X 是匿名函数的参数名称。