简体   繁体   English

如何理解clojure core.async中的alt

[英]how to understand alt in clojure core.async

I have read the following document and the example, but still doesn't get what it really means. 我已经阅读了以下文档和示例,但仍未理解其真正含义。 I understand alts!!, but not alt!!.Anybody show an example easy to understand? 我了解alt !!,但不了解alt !!。有人展示出易于理解的示例吗?

https://clojure.github.io/core.async/#clojure.core.async/alt !! https://clojure.github.io/core.async/#clojure.core.async/alt

I have also ready the following link 我还准备了以下链接

In Clojure (core.async) what's the difference between alts and alt? 在Clojure(core.async)中,alt和alt有什么区别?

update: The example is in the doc is: 更新:该示例在文档中是:

(alt!
  [c t] ([val ch] (foo ch val))
  x ([v] v)
  [[out val]] :wrote
  :default 42)

for the second line of 对于第二行

[c t] ([val ch] (foo ch val))

channel-op of [ct] means a channel c and an value t: put value t on channel c. [ct]的channel-op表示通道c和值t:将值t放在通道c上。 result-expr of ([val ch] (foo ch val)) means bidding [val ch] for the operation, but since it's a list, [val ch] should be evaluate as a function, and (foo ch val) will be as the parameter passed to function of [val ch]. ([[val ch](foo ch val))的result-expr表示对该操作出价[val ch],但是由于它是一个列表,因此[val ch]应该作为一个函数求值,而(foo ch val)将是作为传递给[val ch]函数的参数。 but what does it mean for function of [val ch] with parameter of (foo ch val) ? 但是对于[foo ch val)参数的[val ch]函数意味着什么呢?

[ct] ([val ch] (foo ch val)) [ct]([val ch](foo ch val))

There are some cases where a list doesn't mean "evaluate as a function". 在某些情况下,列表并不意味着“按函数求值”。 For example: 例如:

(ns com.foo.bar
  (:require …))

In the above code, there is no function called :require being called. 在上面的代码中,没有调用称为:require函数。

Another example of lists being used for something other than function application is letfn : 列表用于功能应用程序letfn其他示例是letfn

(letfn [(foo [x] (+ (bar 1) x))
        (bar [x] (+ 2 x))]
  (+ (foo 5) (bar 7)))

As you can see above, letfn has two lists, one starting with the symbol foo , and one starting with the symbol bar , and neither of these lists is a traditional function call. 如上所示, letfn有两个列表,一个以符号foo开头,一个以符号bar开头,并且这些列表都不是传统的函数调用。 Instead, letfn is defining two new functions, one with the name foo , and the other with the name bar . 相反, letfn 定义了两个新函数,一个名为foo ,另一个名为bar The rest of the expression is treated as a "body" in which to use those functions. 表达式的其余部分被视为在其中使用这些功能的“主体”。

but what does it mean for function of [val ch] with parameter of (foo ch val) ? 但是对于[foo ch val)参数的[val ch]函数意味着什么呢?

Similar to letfn , alt defines a value named val and a channel named ch , and then the rest of the expression ( (foo ch val) ) is treated as a "body" in which to use those two names. letfn相似, alt 定义一个名为val的值和一个名为ch ,然后将表达式的其余部分( (foo ch val) )视为在其中使用这两个名称的“ body”。

Explanation of alt!/alt!! alt!/alt!! :

I find it easiest to think of alt! 我发现最容易想到alt! and alt!! alt!! as being somewhat like cond , except instead of testing conditions to choose a body to execute, it waits on channels to choose a body to execute. 就像cond一样,除了不测试条件来选择要执行的主体,而是等待通道来选择要执行的主体。 Each clause consists of two parts, just like cond – the first part (the "channel op" ) is used to specify a channel that alt! 每个子句都由两部分组成,就像cond一样–第一部分( “ channel op” )用于指定alt!通道alt! should wait on, and the second part (the "result expr" ) specifies what should happen if that channel delivers a value first. 应该等待,第二部分( “ result expr” )指定如果该通道首先提供一个值将发生什么。

Since you probably want to access the value delivered by the channel or the channel itself when this happens, the result expr gives you the opportunity to bind both the value and the channel to symbols, and a body of code to execute with those bindings. 由于发生这种情况时您可能想访问通道通道本身传递的值,因此结果expr使您有机会将值和通道都绑定到符号,并使用这些绑定执行代码体。 Thus, the following clause… 因此,以下条款…

[c t]
([val ch]
  (foo ch val))

…means: …手段:

One of the channel operations that this call to alt! 此调用alt!的通道操作之一alt! should block on is an attempt to take from either of two channels, c or t . 应该阻止上是从任一两个通道中, 采取一种尝试ct If either of those send a value before any other channel op in this call to alt! 如果其中一个在此调用alt!任何其他通道op之前发送了一个值alt! , then execute (foo ch val) with val bound to the value taken from the channel that first delivered a value, and with ch bound to the channel that delivered val (which will be either c or t ). ,然后执行(foo ch val) ,将val绑定到从第一个传递值的通道获取的值,并将ch绑定到传递val的通道(将为ct )。

and the following clause… 以及以下条款…

[[out input-val]]
([val ch]
  (bar ch val))

…means: …手段:

One of the channel operations that this call to alt! 此调用alt!的通道操作之一alt! should block on is an attempt to put input-val onto a channel called out . 应该阻塞on是试图 input-val放到一个名为out的通道上。 If that succeeds before any other channel op in this call to alt! 如果该操作在此调用alt!任何其他通道op之前成功完成alt! , then execute (bar ch val) with val bound to input-val and ch bound to out (the channel that successfully received the value). ,然后执行(bar ch val) ,将val绑定到input-val ,将ch绑定到out (成功接收该值的通道)。

Altogether, these two clauses would be written as: 这两个子句总共写为:

(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)))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM