如何理解clojure core.async中的alt
我已经阅读了下面的文档和示例,但仍然没有理解它的真正含义。我理解alts!!,但不是alt!!。有人举一个容易理解的例子吗 我还准备了以下链接 更新:文档中的示例为:如何理解clojure core.async中的alt,clojure,core.async,Clojure,Core.async,我已经阅读了下面的文档和示例,但仍然没有理解它的真正含义。我理解alts!!,但不是alt!!。有人举一个容易理解的例子吗 我还准备了以下链接 更新:文档中的示例为: (alt! [c t] ([val ch] (foo ch val)) x ([v] v) [[out val]] :wrote :default 42) 第二行 [c t] ([val ch] (foo ch val)) 信道op of[c t]表示信道c和值t:将值t置于信道c上。 expr of([v
(alt!
[c t] ([val ch] (foo ch val))
x ([v] v)
[[out val]] :wrote
:default 42)
第二行
[c t] ([val ch] (foo ch val))
信道op of[c t]表示信道c和值t:将值t置于信道c上。
expr of([val ch](foo ch val))的结果表示为操作投标[val ch],但由于它是一个列表,[val ch]应作为函数进行评估,(foo ch val)将作为传递给[val ch]函数的参数。但对于参数为(foo ch val)的[val ch]函数来说,这意味着什么呢
[c t]([val ch](foo ch val))
有些情况下,列表并不意味着“作为函数进行评估”。例如:
(ns com.foo.bar
(:require …))
在上述代码中,没有调用函数:require
用于函数应用程序以外的其他用途的列表的另一个示例是letfn
:
(letfn [(foo [x] (+ (bar 1) x))
(bar [x] (+ 2 x))]
(+ (foo 5) (bar 7)))
如上所述,letfn
有两个列表,一个以符号foo
开头,另一个以符号bar
开头,这两个列表都不是传统的函数调用。相反,letfn
定义了两个新函数,一个名为foo
,另一个名为bar
。表达式的其余部分被视为使用这些函数的“主体”
但对于参数为(foo ch val)的[val ch]函数来说,这意味着什么呢
与letfn
类似,alt
定义一个名为val
的值和一个名为ch
的通道,然后表达式的其余部分((foo ch val)
)被视为一个“主体”,在其中使用这两个名称
解释alt/alt代码>:
我发现最容易想到alt代码>和alt
有点像cond,除了不测试选择要执行的主体的条件外,它在通道上等待选择要执行的主体。每个子句由两部分组成,就像cond
——第一部分(channel op)用于指定alt
应该等待,第二部分(result expr“)指定如果该通道首先传递值,应该发生什么
由于发生这种情况时,您可能希望访问通道或通道本身传递的值,因此,结果expr为您提供了将值和通道绑定到符号的机会,以及使用这些绑定执行的代码体。因此,以下条款
[c t]
([val ch]
(foo ch val))
[[out input-val]]
([val ch]
(bar ch val))
……是指:
此调用调用的通道操作之一alt“代码>应阻止打开”是指尝试从两个通道中的任何一个进行读取,c
或t
。如果其中任何一个在调用alt时在任何其他频道op之前发送一个值
,然后执行(foo ch val)
,将val
绑定到从第一个传递值的通道获取的值,并将ch
绑定到传递val
的通道(将是c
或t
)
下面的条款
[c t]
([val ch]
(foo ch val))
[[out input-val]]
([val ch]
(bar ch val))
……是指:
此调用调用的通道操作之一alt代码>应阻止打开是试图将输入值
放入名为输出
的频道。如果该操作在调用alt的任何其他频道op之前成功
,然后执行(条形通道val)
,将val
绑定到input val
,并将ch
绑定到out
(成功接收值的通道)
这两条条文的内容合共如下:
(alt!
[c t] ; "Takes" can be a single channel instead of vectors.
([val ch]
(foo ch val))
[[out input-val]] ; "Puts" must be nested vectors.
([val ch]
(bar ch val)))
你不明白哪一部分?我想你对第二行的理解有点偏离<代码>[c t]
是端口向量<代码>[val ch]
是一种绑定(如您所说)ch
是可以从中获取的频道;而val
是所取的值。然后使用该绑定对函数foo
进行评估。请看一个简单的例子,这是一个非常清晰的例子。最好写在官方文件上:)谢谢erikprice,很好的解释。[c t]的一个问题是,c和t频道是否都像科纳克雷特的节目?我再次阅读文档,如果它是[[c t]],那么c是一个放置通道,t是要放置的值。如果只是[c t],那么两者都应该是频道,对吗?@DanielWu是的,你是对的。我错误地将向量表示为“put”操作,但是“put”需要嵌套的向量,正如您所描述的,非嵌套的向量只是多个要“获取”的通道。我已经更新了答案,以反映更正,使其显示为“接受”和“出售”。