关于`||`在erlang中的使用
About the usage of `||` in erlang
我正在阅读项目recon
的源代码,
我发现一个有趣的代码:
proc_attrs(binary_memory, Pid) ->
case process_info(Pid, [binary, registered_name,
current_function, initial_call]) of
[{_, Bins}, {registered_name,Name}, Init, Cur] ->
{ok, {Pid, binary_memory(Bins), [Name || is_atom(Name)]++[Init, Cur]}};
undefined ->
{error, undefined}
end;
在这段代码中,有一个[Name || is_atom(Name)]
,
我正在尝试 shell:
27> [a || is_atom(a)].
[a]
28> [a || is_atom("a")].
[]
29> [a || true].
[a]
30> [a || false].
[]
但是我从来没有见过这样的用法,谁能告诉我细节?
[ ... || ... ]
是一个list comprehension,通常用于对一个列表进行操作以产生另一个列表。在这种情况下,仅使用理解的生成器侧(右侧)的过滤器部分作为条件,并且与往常一样,仅当过滤器通过时,左侧才会产生值。考虑你的例子:
27> [a || is_atom(a)].
[a]
28> [a || is_atom("a")].
[]
在命令 27 中,a
确实是一个原子,因此过滤器 is_atom/1
通过,因此左侧产生值 [a]
。但是在命令 28 中,is_atom/1
过滤器消除了值 "a"
,因为它不是原子,左侧什么也不产生,所以结果是一个空列表。
这种方法是 shorthand 编写更长条件语句的方法。例如,您从 recon 引用的以下代码:
[Name || is_atom(Name)]++[Init, Cur]
也可以写成:
case is_atom(Name) of true -> [Name]; false -> [] end ++ [Init, Cur]
有人可能会说后者更容易理解,但显然它也更冗长,因此可能会使代码过于混乱。
我正在阅读项目recon
的源代码,
我发现一个有趣的代码:
proc_attrs(binary_memory, Pid) ->
case process_info(Pid, [binary, registered_name,
current_function, initial_call]) of
[{_, Bins}, {registered_name,Name}, Init, Cur] ->
{ok, {Pid, binary_memory(Bins), [Name || is_atom(Name)]++[Init, Cur]}};
undefined ->
{error, undefined}
end;
在这段代码中,有一个[Name || is_atom(Name)]
,
我正在尝试 shell:
27> [a || is_atom(a)].
[a]
28> [a || is_atom("a")].
[]
29> [a || true].
[a]
30> [a || false].
[]
但是我从来没有见过这样的用法,谁能告诉我细节?
[ ... || ... ]
是一个list comprehension,通常用于对一个列表进行操作以产生另一个列表。在这种情况下,仅使用理解的生成器侧(右侧)的过滤器部分作为条件,并且与往常一样,仅当过滤器通过时,左侧才会产生值。考虑你的例子:
27> [a || is_atom(a)].
[a]
28> [a || is_atom("a")].
[]
在命令 27 中,a
确实是一个原子,因此过滤器 is_atom/1
通过,因此左侧产生值 [a]
。但是在命令 28 中,is_atom/1
过滤器消除了值 "a"
,因为它不是原子,左侧什么也不产生,所以结果是一个空列表。
这种方法是 shorthand 编写更长条件语句的方法。例如,您从 recon 引用的以下代码:
[Name || is_atom(Name)]++[Init, Cur]
也可以写成:
case is_atom(Name) of true -> [Name]; false -> [] end ++ [Init, Cur]
有人可能会说后者更容易理解,但显然它也更冗长,因此可能会使代码过于混乱。