2024 Clojure 状态调查! 中分享您的想法。

欢迎!请访问关于 页面,了解有关如何使用此功能的一些更多信息。

0
引用、代理、原子

我知道一点 Lisp,但 Clojure 感觉有点不同

(defn mojorate []
  (let [v (vec (range 1 11))
        max (- (count v) 1)
        atomix (atom [])
        chanl (async/chan)]
    (println v)
    (loop [i 0]
      (async/go
        (>! chanl (swap! atomix conj (/ (get v i) 2))))
      (if (= i max)
        (do (<!! (async/go (<! chanl)))
          (async/close! chanl)
          @atomix)
        (recur (inc i))))))

这只是关于通道、原子 loop/recur 等的练习。

你能这样做吗?

我不确定你到底问的是什么 - 你能详细说明一下吗?
它按预期工作,但我不确定它是否是1.:惯用2.:最佳实践。3.:或者可以做得更好。
但“预期”是什么意思?函数*本来*应该做什么?运行它时,我会在不同的运行中看到不同的结果,所以我无法确切地推断你真正需要什么。
我总是得到
testomato.core> (mojorate)
[1 2 3 4 5 6 7 8 9 10]                                                                      
[1/2 1 3/2 2 5/2 3 7/2 9/2 5]

这个片段将10个数字发送到通道中,并接收回来 - 除以二。

1 条答案

+1

您太多使用了go块,不仅代码中的数量很多,执行的数量也很多。循环中的第一个go块不阻塞 - 它允许立即继续执行。不能保证在相同的块再次执行时,前面的块已有足够的时间将值放入通道。这是一个竞态条件。

为了确认,只需运行此代码:(set (repeatedly 10000 mojorate))。如果获得的是只有一个元素的集合,则增加此数字。

这个片段将10个数字发送到通道中,并接收回来 - 除以二。

句子的前半部分是实现细节,从函数用户的角度看,这点无关紧要。如果您需要获取从1开始的10个数字的向量,除以2,那么当然有(mapv #(/ % 2) (range 1 11))

如果您需要其他东西,请详细描述,以免陷入XY问题。原始函数可以以多种方式进行重写 - 如果您的真实问题需要特殊的解决方案,则其中任何一种都可能不正确。

我试图熟悉这个概念。然后我意识到 mapv 是一个更紧致的解决方案。简单的算术并不罕见,可以展示类似的东西。以下是一个 Common Lisp 的示例

(let ((channel (make-channel)))
  (submit-task channel '+ 3 4)
  (receive-result channel))

但是我可以确认你预测的结果:进行 100,000 次重复后,我得到了

#{[1/2 1 3/2 2 5/2 3 7/2 4 9/2 5]
  [1 3/2 2 5/2 3 7/2 4 9/2 5 1/2]
  [1/2 1 3/2 2 5/2 3 7/2 4 9/2]
  [1/2 1 2 5/2 3 7/2 4 9/2 5 3/2]}
据我所知,Common Lisp 中的通道与 `clojure.core.async` 中的通道不相同。它们更像是与特定线程进行通信的一种方式。在 Clojure 中,如果你只想在单独的线程中运行一系列计算,最好的办法是只使用 `future` 或 `pmap`(尽管通常建议避免使用 `pmap`,而使用可以控制的替代方案)。如果你想在某个位置输入值,也许在第二个位置对其进行一些计算,然后在第三个位置接收结果,而这些位置可能根本不知道彼此,异步通道在 Clojure 中就很有用了。例如,生产者可能会使用 `(a/to-chan! (range 1 11))`,转换器可能会使用 `(a/map #(/ % 2) [channel])`,消费者可能会使用 `(a/go (let [all-values (a/<! (a/into [] transformed-channel))] ...))`。
当然,Clojure 中的通道远不止这些。它们支持使用不同的策略进行缓冲,允许进行背压,允许您静态或动态地组合和分离通道……
by
重新提出 by
谢谢。我现在开始清楚地看到这一点。我真的没有看到竞争条件。
...