2009-10-15 132 views
3

我无法理解这条线。需要帮助理解这个erlang代码

[Pid2 ! {delete, V1a} 
    || {Pid1a, V1a} <- PV1a, Pid2 <- P2, Pid1a /= Pid2 
    ], 

这里是我的理解:双管之前 什么“||”根据双管之后的情况反复进行。因此带有删除原子的消息会重复发送到Pid2。 我知道'/ ='意味着不平等。我不明白'< - '是什么意思,最终意味着什么。

+0

将标题改为“了解Erlang中的列表理解”会很好。 – Christian 2009-10-15 06:11:57

回答

15

[something(X) || X <- L],是一个列表理解。 L是一个元素列表,这个表达式创建一个新元素的列表,通过调用something()来形成每个元素。

[something(X,Y) || X <-L, Y<-M]是类似的,但对于在X的每个元素和Y

​​的笛卡儿积将创建一个元件是过滤器表达式。与第一个相同,但仅针对L的元素执行,其中Expr对于给定的X为真。

[something(X) || {X,..} <-L, Expr]是另一种过滤器。在列表理解中,只有那些可以被元素匹配的元素。

还有一件事要知道的是,这不仅可以用于生成另一个列表,而且还可以为每个元素执行一个命令。如果列表理解的结果不匹配,编译器将根本不知道生成列表。此行为可用于模仿其他语言的foreach

一些例子:

1> [ X*2 || X <- [1,2,3] ]. 
[2,4,6] 
2> [ X*Y || X <- [1,2], Y <- [3,4,5] ]. 
[3,4,5,6,8,10] 
3> [ X*3 || X <- [1,2,3,4], X rem 2 == 0 ]. 
[6,12] 
4> [ X || {a,X} <- [{a,1},{a,2},{b,3},{c,4}] ]. 
[1,2] 

所以,你的代码生成从P2 PV1a和PID2元素都{Pid1a,V1A}元素的笛卡尔乘积,除了其中Pid1a等于PID2这些元素,并为每个这些对发送{delete,V1a}消息到Pid2。

5

我不知道Erlang,但这看起来就像我知道的一堆语言的列表解析。希望这个猜测会帮助你,直到有人谁知道二郎可以回答:

[Pid2 ! {delete, V1a} || {Pid1a, V1a} <- PV1a, Pid2 <- P2, Pid1a /= Pid2], 

转化为命令式的伪代码:

For each item in PV1a, unpacking item to {Pid1a, V1a} 
    For each Pid2 in P2 
     If Pid1a /= Pid2 
      Pid2 ! {delete, V1a} 

换句话说,每个PID在PV1a和P2,发送邮件只要Pid1和Pid2不是相同的Pid,就删除V1a到Pid2。

+0

你能解释一下拆包的部分吗?解包是什么意思? – Quincy 2009-10-15 04:46:10

+0

这里我们使用模式匹配来首先检查列表PV1a的元素是两个元素的元组,并将元组拉开到它的元素Pid1a和V1a。模式匹配是erlang的基础,在erlang代码中无处不在。 – rvirding 2009-10-15 10:14:14

1

这是一个list comprehension和< - 运算符用于生成器。

看看LC的更受欢迎的介绍示例;找到三角形,其中整数边的平方等于整数斜边的平方,但对于给定的整数范围Ns

​​

这给了我们以下列表作为输出。

[{3,4,5},{4,3,5}] 

这似乎是正确的:

3² + 4² = 5² 
9 + 16 = 25 
25 = 25 

所以列表理解可以理解为给我们每一个X,Y和C使得X是从Ns个取,Y是从Ns和C线是取自Ns,X 2 + Y 2等于C 2。