erlang记录麻烦

use*_*836 6 erlang records

我正在努力学习其中一个模块中的记录.

我在我的代码之上定义了一条记录:

-record(user,  {pid,
                name,
                nick}).
Run Code Online (Sandbox Code Playgroud)

用几个词来说,每个用户将被表示为具有自己的pid和其他字段的进程.

稍后在模块中我将执行以下操作:

Pid = UserPid,
GetUser = fun(X) ->
                if X#user.pid =:= Pid -> true; 
                   X#user.pid=/= Pid -> false 
                end 
      end,
User = lists:filter(GetUser, Users),
io:format("User pid is ~p~n",[User#user.pid]).
Run Code Online (Sandbox Code Playgroud)

运行此代码我得到:

** exception error: {badrecord,user}
Run Code Online (Sandbox Code Playgroud)

但如果我这样做:

io:format("User ~p~n",[User]).       
Run Code Online (Sandbox Code Playgroud)

它打印

User [{user,<0.33.0>,name1,nick1}]
Run Code Online (Sandbox Code Playgroud)

任何人都可以指出我错过了什么?

谢谢

Emi*_*nov 11

问题是lists:filter返回另一个列表,而不是单个元素.所以你基本上试图将列表视为记录.如果你仔细看看输出

io:format("User ~p~n",[User])
%% User [{user,<0.33.0>,name1,nick1}]
Run Code Online (Sandbox Code Playgroud)

你会注意到该声明被包含在内[].这是一个清单.如果您只需要第一个用户使用

[First | Rest] = lists:filter(GetUser, Users)
Run Code Online (Sandbox Code Playgroud)

如果您只想使用pids lists:map:

UsersWithPid = lists:filter(GetUser, Users),
Pids = lists:map(fun(U) -> U#user.pid end, UsersWithPid).
Run Code Online (Sandbox Code Playgroud)

现在Pids列出带有pid的用户的pids.

  • 请注意,[First,Rest]将匹配具有两个元素的列表.你可能想要:[首先|休息].或者,如果您期望一个结果:[First]. (2认同)

Rob*_*loi 7

埃米尔关于the lists:filter功能的答案是正确的.

这是我重写代码的方式:

-module(com).

-record(user,  {pid,
                name,
                nick}).

-export([lookup/1]).

lookup(Pid) ->
    Users = users(),
    FilteredUsers = [User || #user{pid = P} = User <- Users, Pid =:= P],
    lists:foreach(fun display/1, FilteredUsers).

display(User) ->
    io:format("User name  is ~p~n",[User#user.name]).   

users() ->
    User1 = #user{pid = 1, name = "Bob", nick = "bob"},
    User2 = #user{pid = 2, name = "Alice", nick = "alice"},
    User3 = #user{pid = 1, name = "Charlie", nick = "charlie"},
    [User1, User2, User3].
Run Code Online (Sandbox Code Playgroud)

我假设你可以有多个pids.如果你不这样做,你就可以省去自己.

我相信在这种情况下使用列表推导使代码更具可读性.另外,以下内容:

Pid = UserPid,

对我来说看起来不是很有用......

  • 我会做`[U || U < - Users,U#user.pid =:= P]`. (3认同)