如何在 Erlang 中为字符串变量重新赋值?
How to reassign value to string variables in 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",
我得到同样的错误。
非常感谢你的帮助。
你不能。 Erlang 有一个特性叫做 "single assignment",这意味着你不能在第一次赋值后改变变量的值。如果您尝试这样做,它会变成模式匹配,并且您会收到 badmatch
错误,就像您尝试 "test1" = "test2"
.
一样
你的例子可以写成:
A =
if
Condition ->
"test2";
true ->
"test1"
end
有关单一作业的更多信息,请参阅 this question 及其答案。
在您的扩展示例中,您尝试做的事情可以通过折叠来实现。也就是说,给定一个列表和一个名为 "accumulator" 的附加值,遍历列表并为每个元素调用一个函数,并让该函数的 return 值成为新的累加器 - 并且 return最后的累加器
为此使用 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).
=
不是 erlang 中的赋值运算符,而是 模式匹配 运算符。
如果你写:
{A, hello} = {10, hello}.
和A
还没有绑定到(或者你可以说分配)一个值,然后erlang尝试为右侧创建一个匹配项(因为 =
是匹配运算符)。要为右侧创建匹配项,erlang binds/assigns 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
。
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
是匿名函数参数的名称。
我是 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",
我得到同样的错误。
非常感谢你的帮助。
你不能。 Erlang 有一个特性叫做 "single assignment",这意味着你不能在第一次赋值后改变变量的值。如果您尝试这样做,它会变成模式匹配,并且您会收到 badmatch
错误,就像您尝试 "test1" = "test2"
.
你的例子可以写成:
A =
if
Condition ->
"test2";
true ->
"test1"
end
有关单一作业的更多信息,请参阅 this question 及其答案。
在您的扩展示例中,您尝试做的事情可以通过折叠来实现。也就是说,给定一个列表和一个名为 "accumulator" 的附加值,遍历列表并为每个元素调用一个函数,并让该函数的 return 值成为新的累加器 - 并且 return最后的累加器
为此使用 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).
=
不是 erlang 中的赋值运算符,而是 模式匹配 运算符。
如果你写:
{A, hello} = {10, hello}.
和A
还没有绑定到(或者你可以说分配)一个值,然后erlang尝试为右侧创建一个匹配项(因为 =
是匹配运算符)。要为右侧创建匹配项,erlang binds/assigns 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
。
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
是匿名函数参数的名称。