我已经阅读了以下文档和示例,但仍然没有得到它的真正含义。我理解alts !!,但不是alt !!。有人举一个容易理解的例子吗?
https://clojure.github.io/core.async/#clojure.core.async/alt !!
我还准备了以下链接
In Clojure (core.async) what's the difference between alts and alt?
更新:示例位于doc:
(alt!
[c t] ([val ch] (foo ch val))
x ([v] v)
[[out val]] :wrote
:default 42)
第二行
[c t] ([val ch] (foo ch val))
[c t]的通道操作意味着通道c和值t:将值t放在通道c上。 ([val ch](foo ch val))的result-expr表示操作的出价[val ch],但由于它是一个列表,[val ch]应该作为函数计算,并且(foo ch val)将是作为参数传递给[val ch]的函数。但是对于具有(foo ch val)参数的[val ch]的函数意味着什么?
答案 0 :(得分:5)
[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
。表达式的其余部分被视为使用这些函数的“主体”。
但是[val ch]的函数对于(foo ch val)的参数是什么意思?
与letfn
类似,alt
定义名为val
的值和名为ch
的频道,然后是表达式的其余部分( (foo ch val)
)被视为使用这两个名称的“主体”。
alt!/alt!!
:我觉得最容易将alt!
和alt!!
视为有点像cond
,除了测试选择要执行的主体的条件,它会等待频道选择身体执行。每个子句由两部分组成,就像cond
一样 - 第一部分(“channel op”)用于指定alt!
应该等待的频道,以及第二部分(“结果expr”)指定如果该频道首先传递值,会发生什么。
由于您可能希望在发生这种情况时访问通道或通道本身提供的值,结果expr 使您有机会同时绑定值和通道到符号,以及用这些绑定执行的代码体。因此,以下条款......
[c t]
([val ch]
(foo ch val))
...是指:
此
alt!
调用应阻止的其中一个频道操作是尝试从<{1}}或c
两个频道中选择。如果其中任何一个在此t
调用中的任何其他频道操作之前发送了一个值,则执行alt!
,(foo ch val)
绑定到从频道获取的值首先投放了一个值,并val
绑定到投放ch
的频道(val
或c
)。
以及以下条款......
t
...是指:
此
[[out input-val]] ([val ch] (bar ch val))
调用应阻止的其中一个频道操作是将alt!
置于名为input-val
的频道上。如果在此次out
调用中的任何其他频道操作之前成功,请执行alt!
(bar ch val)
绑定val
和input-val
绑定到ch
(成功接收该值的通道)。
总而言之,这两个条款将写成:
out