Clojure 使用core.async';s>;!而且<;!外围棋区

Clojure 使用core.async';s>;!而且<;!外围棋区,clojure,Clojure,我试图在clojure中实现一个(非常)简单的演员模型原型。作为处理消息到达的循环,每个参与者都有一个go循环。我想在这个go循环中调用函数,这些函数要么从通道中获取,要么放入通道中。我真的很想在这些内部通道操作上实现停车行为,但我实际上不能使用或>这样做,因为操作不会直接在go循环中进行。我可以使用宏来规避这种限制吗?如果是,我会怎么做 为了简单地说明这个问题,在下面的代码片段中,我如何更改foo,使代码能够实际编译并获得停车行为 (defn main-loop [ch] (async

我试图在clojure中实现一个(非常)简单的演员模型原型。作为处理消息到达的循环,每个参与者都有一个
go循环
。我想在这个
go循环中调用函数,这些函数要么从通道中获取,要么放入通道中。我真的很想在这些内部通道操作上实现停车行为,但我实际上不能使用
>
这样做,因为操作不会直接在
go循环中进行。我可以使用宏来规避这种限制吗?如果是,我会怎么做

为了简单地说明这个问题,在下面的代码片段中,我如何更改
foo
,使代码能够实际编译并获得停车行为

(defn main-loop
  [ch]
  (async/go-loop [] (foo ch) (recur)))
(defn foo [ch] (>! ch "Hello, World!"))

正如Carcigenicate所说,<代码>>表单必须位于
go
循环中,因为它只是一个执行代码生成/重新格式化的巨大宏。另请注意,
>
不能在
go
循环中调用的函数内,因为
go
宏无法在被调用函数内查看以进行必要的重新格式化

>
form确实简单地使用java线程和锁来进行必要的同步,但这是一个您不应该担心的微观成本

为方便起见,我喜欢将异步函数考虑如下:

  >!    =>  "put-go"     (must be in a go loop - parking semantics)
  >!!   =>  "put-now"    (can be anywhere - blocking/immediate effect)
  put!  =>  "put-later"  (can be anywhere - non-blocking/delayed effect)

您可以看到这些函数的一些示例。

正如Carcigenicate所说,
>表单必须位于
go
循环中,因为它只是一个执行代码生成/重新格式化的巨大宏。另请注意,
>
不能在
go
循环中调用的函数内,因为
go
宏无法在被调用函数内查看以进行必要的重新格式化

>
form确实简单地使用java线程和锁来进行必要的同步,但这是一个您不应该担心的微观成本

为方便起见,我喜欢将异步函数考虑如下:

  >!    =>  "put-go"     (must be in a go loop - parking semantics)
  >!!   =>  "put-now"    (can be anywhere - blocking/immediate effect)
  put!  =>  "put-later"  (can be anywhere - non-blocking/delayed effect)

您可以看到这些函数的一些示例。

您可以使用宏编写任何可以手动编写的代码,仅此而已。因此,如果您只是想让您的函数成为方便快捷的使用
>内联,然后确定,您可以用宏替换函数。如果您想做一些更有趣的事情,比如将该函数映射到消息列表上,那么您就做不到,因为这需要将它们捆绑在一个函数中,以传递给
map

一个简单的例子就是

(defmacro foo [ch]
  `(>! ~ch "Hello, World!"))

这是您问题的解决方案,还是其他解决方案(例如使用
!!
),取决于您希望如何处理这些问题。

您可以使用宏来编写任何可以手动编写的代码,仅此而已。因此,如果您只是想让您的函数成为方便快捷的使用
>内联,然后确定,您可以用宏替换函数。如果您想做一些更有趣的事情,比如将该函数映射到消息列表上,那么您就做不到,因为这需要将它们捆绑在一个函数中,以传递给
map

一个简单的例子就是

(defmacro foo [ch]
  `(>! ~ch "Hello, World!"))

这是您问题的解决方案,还是其他解决方案(如使用
!!
),取决于您希望如何处理这些问题。

您不能。它们必须一次性使用<代码>>
不是一个实际执行任何操作的函数。它们被翻译成有用的代码。它们只是地方标记。在IntelliJ中使用ctrl+B查找它们的定义。我对
async
的经验不足,无法确切知道
go
s何时合适,但为什么不能在这里使用
go
?这将是一个不同的程序。这本书并不是说它能做任何有用的事情——它只会永远打印“你好,世界!”——但我只是想提供一个小小的说明,你不能。它们必须一次性使用<代码>>
不是一个实际执行任何操作的函数。它们被转换成有用的代码。它们只是地方标记。在IntelliJ中使用ctrl+B查找它们的定义。我对
async
的经验不足,无法确切知道
go
s何时合适,但为什么不能在这里使用
go
?这将是一个不同的程序。并不是说这一个会理想地做任何有用的事情——它只会永远打印“Hello,World!”——但我只是想提供一个小说明使用
不会导致阻塞go块的线程池,而不仅仅是阻塞使用它的go块内的线程吗?提供了有关停止/阻塞线程的rational和更多详细信息的良好概述。使用
不会导致阻塞go块的线程池,而不仅仅是阻塞使用它的go块内的线程吗?提供了rational的一个很好的概述,以及关于驻车/阻塞线程的更多细节。