Clojure原子将向量转换为列表?
我想要一个原子中的Clojure向量来模拟一个有状态的FIFO(推到底,从头开始弹出)。尝试 然后按下Clojure原子将向量转换为列表?,clojure,Clojure,我想要一个原子中的Clojure向量来模拟一个有状态的FIFO(推到底,从头开始弹出)。尝试 然后按下按钮,如下所示: (swap! stack #(conj % 1)) (swap! stack #(conj % 2)) 期待 [1 2] 但是 (2 1) 这没什么大不了的,只是意味着我必须反转原子(持久列表)的值(O(n))才能按顺序获得项目,而不是按顺序推送它们(例如,按顺序将命令流发送到虚拟机)。尽管如此,这还是一个惊喜 是否有一个clojure.core FIFO可以打包成一个原
按钮,如下所示:
(swap! stack #(conj % 1))
(swap! stack #(conj % 2))
期待
[1 2]
但是
(2 1)
这没什么大不了的,只是意味着我必须反转原子(持久列表)的值(O(n))才能按顺序获得项目,而不是按顺序推送它们(例如,按顺序将命令流发送到虚拟机)。尽管如此,这还是一个惊喜
是否有一个clojure.core FIFO可以打包成一个原子?我想到了优先级映射
,但似乎有些过头了。swap使用列表或地图,这不是我想要的。我通过谷歌搜索“FIFO Clojure”找到了很多样本,但有些样本有点丰富,例如Clojure.core.cache(类似于地图而不是向量);阿马洛伊环形缓冲器(外部依赖)。寻找一些真正小而直接的东西。我在StackOverflow的自动建议中没有看到答案。在您的代码的更广泛上下文中,有些东西不太正确;我假设你有比你贴的例子更多的东西
以下是我的REPL中的结果和我的期望:
user=> (def stack (atom []))
#'user/stack
user=> (swap! stack #(conj % 1))
[1]
user=> (swap! stack #(conj % 2))
[1 2]
user=> @stack
[1 2]
使用向量时,项目将添加到集合的末尾。您看到的结果看起来像是如果stack
是一个列表,您将得到的行为,例如,在前面添加:
user=> (def stack (atom '()))
#'user/stack
user=> (swap! stack #(conj % 1))
(1)
user=> (swap! stack #(conj % 2))
(2 1)
user=> @stack
(2 1)
所以我想知道,在代码的某个地方,您是否最终定义了一个列表,而不是一个向量。上下文是一系列重复的推送和弹出测试。看起来,当我从向量堆栈中弹出最后一项时,原子留下了一个空列表,而不是一个空向量。后续操作将conj推到列表而不是向量上。在我的pop函数中,修复很容易——如果最后一个pop清空堆栈,则放回一个空向量。不,(pop[1])
是[]
。那不是你的问题。现在,如果你在它上面调用rest
,或者seq
,这可能会使它成为一个列表。我编写了自己的(愚蠢的,错误的)pop函数,它调用了(部分删除1)
,无意中进行了转换。固定使用内置的pop。嗯,内置的pop
pop从向量的末尾弹出,所以我认为它以最直接的用法实现了后进先出。当atom中的seq为空时,我暂时使用(swap!fifo(fn[\u][])
。如果需要队列而不是堆栈,只需使用clojure.lang.PersistentQueue
中的内置队列即可。
user=> (def stack (atom '()))
#'user/stack
user=> (swap! stack #(conj % 1))
(1)
user=> (swap! stack #(conj % 2))
(2 1)
user=> @stack
(2 1)