如何理解clojure core.async中的alt

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)的参数意味着什么?

eri*_*ice 6

[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(这将是任一ct).

和以下条款......

[[out input-val]]
([val ch]
  (bar ch val))
Run Code Online (Sandbox Code Playgroud)

…手段:

此调用alt!应阻止的其中一个通道操作是尝试放入 input-val一个被调用的通道out.如果成功之前的任何其它信道的运算在该调用alt!,则执行(bar ch val)val结合至input-valch结合到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)