找到if语句记录中的一个成员

时间:2015-01-12 23:30:11

标签: erlang

我正在尝试查看当前记录是否包含该成员。

#U{name ="roger", age18}

#U{name = "roger"}= User ->
    Same = fun(X) ->
              if X|| {X, X#U.name} <- User -> true;
                true -> false
              end
           end,

我在if语句中收到错误。

错误:非法守卫表达        警告:变量&#39; X&#39;未使用

因为#U可以有多条记录,例如

#U{name ="roger", age=24}
#U{name ="sam", age=23}
#U{name ="rog", age=21}
#U{name ="roger", age=21}
#U{name ="tigr", age=19}

所以当我打电话给#U {name =&#34; roger&#34;} =用户我只列出名称= roger的记录并将其存储在用户中。

而我想要做的是,无论我目前的#U记录如果id与User匹配,那么其他为false。

这个编译但什么也没做。

if X#U.name =:= User 

请帮帮我。我不知道我做错了什么,以及我怎么不使用X ??

1 个答案:

答案 0 :(得分:1)

您的代码示例非常疯狂,所以我将从头开始。

记录是糖衣元组。就是这样。没什么。

Erlang不是C,Algol,Go,Python,Perl等。所以在你已经输入函数后检查ifcond或其他任何内容的特定值的想法身体通常是一种错误的冲动。改为使用匹配。

让我们从标记为{user, Name, Age}的元组开始。我们如何在功能头中匹配?假设我们想编写一个特殊处理名为“Anna Graham”的人的函数,用他们的用户记录做一些事情,在他们的年龄上运行一些函数,然后返回一个元组;有不同名字的人可以得到一些不同的待遇:

do_stuff(U = {user, "Anna Graham", Age}) ->
    A = step1(U),
    B = step2(Age),
    {ok, {A, B}};
do_stuff(U) ->
    Result = other_stuff(U),
    {ok, Result}.

请注意,我们没有绑定Name变量,因为它从未使用过,我们只是直接匹配了名称;任何名字别的人都会遇到默认情况。

现在让我们说我们想要做那个特殊的程序,但只针对年龄为24岁的人:

do_stuff(U = {user, "Anna Graham", Age = 24}) ->
    A = step1(U),
    B = step2(Age),
    {ok, {A, B}};
do_stuff(U) ->
    Result = other_stuff(U),
    {ok, Result}.

我们确实绑定了Age值因为我们使用了它,但我们也可以用这种方式编写该函数:

do_stuff(U = {user, "Anna Graham", 24}) ->
    A = step1(U),
    B = step2(24),
    {ok, {A, B}};
do_stuff(U) ->
    Result = other_stuff(U),
    {ok, Result}.

但是这在代码中隐藏了一个神奇的价值,被认为是草率的编码实践。

那么这些记录呢?这是一些完全等效代码:

-record(user, {Name, Age}).

do_stuff(U#user{name = "Anna Graham", age = 24}) ->
    A = step1(U),
    B = step2(U#user.age),
    {ok, {A, B}};
do_stuff(U) ->
    Result = other_stuff(U),
    {ok, Result}.

(注意我使用术语“完全等效”。我的意思是。编译器实际上在编译时将记录分开,并按照我编写早期版本的方式重写它。记住:Erlang记录不是< / em> Python dicts或Perl哈希或SomeLang中的任何其他K / V东西。在这个简单的案例中,记录可能是矫枉过正的,也许因为语法而更加丑陋;但在大型复杂元组中,它们可以是非常方便的简化。)< / p>

或者我们甚至可以用不同的方式编写函数头,在=上叠加age符号并匹配两者,并立即将其分配给Age

do_stuff(U#user{name = "Anna Graham", age = Age = 24}) ->
    % stuff

但如果她的年龄大于24岁,如果我们需要对这个名字的人做些什么,如果她的年龄小于或等于24岁,请以不同的方式对待她?

do_stuff(U#user{name = "Anna Graham", age = Age}) when Age =< 24 ->
    process_young(U);
do_stuff(U#user{name = "Anna Graham", age = Age}) when > 24 ->
    process_older(U);
do_stuff(U) ->
    other_stuff(U).

或者......也许我们想根据她的年龄与她做点什么,这个中间值会影响她年龄的额外处理。啊哈!现在我们确实有充分的理由在函数中使用ifcond表达式(我们不想写两次初始处理,是吗?):

do_stuff(U#user{name = "Anna Graham", age = Age})
    Preprocessed = step1(U),
    Result = if
        Age >  24 -> older_step2(Preprocessed);
        Age =< 24 -> young_step2(Preprocessed)
    end,
    {ok, Result};
do_stuff(U) ->
    other_stuff(U).

在大多数情况下,您希望在功能头中坚持使用简单的模式匹配。通常这更容易阅读。但是,有时您会遇到预处理值基于某些条件进行进一步处理的情况,但这种情况并不需要完全反汇编成几个新函数,因此ifcond实际上是最好的用法。