Dan*_* Wu 3 clojure core.async
我已经阅读了以下文档和示例,但仍然没有得到它的真正含义.我理解alts !!,但不是alt !!.有人举一个容易理解的例子吗?
https://clojure.github.io/core.async/#clojure.core.async/alt !!
我也准备了以下链接
在Clojure(core.async)中,alts和alt有什么区别?
更新:示例在doc中是:
(alt!
[c t] ([val ch] (foo ch val))
x ([v] v)
[[out val]] :wrote
:default 42)
Run Code Online (Sandbox Code Playgroud)
对于第二行
[c t] ([val ch] (foo ch val))
Run Code Online (Sandbox Code Playgroud)
[ct]的channel-op表示通道c和值t:将值t放在通道c上.([val ch](foo ch val))的result-expr表示操作的出价[val ch],但由于它是一个列表,[val ch]应该作为函数计算,并且(foo ch val)将是作为参数传递给[val ch]的函数.但是[val ch]的函数对于(foo ch val)的参数意味着什么?
[ct]([val ch](foo ch val))
在某些情况下,列表并不意味着"评估为功能".例如:
(ns com.foo.bar
(:require …))
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,没有被称为:require
被调用的函数.
用于除函数应用程序之外的其他内容的列表的另一个示例是letfn
:
(letfn [(foo [x] (+ (bar 1) x))
(bar [x] (+ 2 x))]
(+ (foo 5) (bar 7)))
Run Code Online (Sandbox Code Playgroud)
如上所示,letfn
有两个列表,一个以符号开头,另一个以符号foo
开头bar
,这些列表都不是传统的函数调用.相反,letfn
它定义了两个新函数,一个具有名称foo
,另一个具有名称bar
.表达式的其余部分被视为使用这些函数的"主体".
但是[val ch]的函数对于(foo ch val)的参数意味着什么?
类似于letfn
,alt
定义一个名为value val
和一个名为的通道ch
,然后将expression((foo ch val)
)的其余部分视为使用这两个名称的"body".
alt!/alt!!
:我觉得最容易想到alt!
并且alt!!
有点像cond
,除了测试条件以选择要执行的主体之外,它等待通道选择要执行的主体.每个子句由两部分组成,就像cond
- 第一部分("通道操作")用于指定alt!
应该等待的通道,第二部分("结果表达式")指定如果该通道提供应该发生的情况价值第一.
由于您可能希望在发生这种情况时访问通道或通道本身提供的值,因此结果expr使您有机会将值和通道绑定到符号,以及使用这些绑定执行的代码体.因此,以下条款......
[c t]
([val ch]
(foo ch val))
Run Code Online (Sandbox Code Playgroud)
…手段:
此调用
alt!
应阻止的其中一个通道操作是尝试从两个通道中的任何一个获取,c
或者t
.如果任一那些的任何其他之前发送的值的信道的运算在该调用alt!
,则执行(foo ch val)
与val
结合到从第一传送的值的信道获取的值,并与ch
结合到该传送的信道val
(这将是任一c
或t
).
和以下条款......
[[out input-val]]
([val ch]
(bar ch val))
Run Code Online (Sandbox Code Playgroud)
…手段:
此调用
alt!
应阻止的其中一个通道操作是尝试放入input-val
一个被调用的通道out
.如果成功之前的任何其它信道的运算在该调用alt!
,则执行(bar ch 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)))
Run Code Online (Sandbox Code Playgroud)