如何理解clojure core.async中的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

我已经阅读了下面的文档和示例,但仍然没有理解它的真正含义。我理解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([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”需要嵌套的向量,正如您所描述的,非嵌套的向量只是多个要“获取”的通道。我已经更新了答案,以反映更正,使其显示为“接受”和“出售”。