【问题标题】:Clojure transients usageClojure 瞬态使用
【发布时间】:2012-09-05 07:47:08
【问题描述】:

我对在 clojure 中使用瞬变有点迷茫。任何帮助将不胜感激。 示例代码:

(defn test-transient [v]
    (let [b (transient [])]
        (for [x v] (conj! b x))
        (persistent! b)))

user> (test-transient [1 2 3])
[]

我尝试在返回之前使其持久化,结果是:

(defn test-transient2 [v]
    (let [b (transient [])]
        (for [x v] (conj! b x))
        (persistent! b)
        b))

user> (test-transient2 [1 2 3])
#<TransientVector clojure.lang.PersistentVector$TransientVector@1dfde20>

但是如果我使用 conj!单独看来工作正常:

(defn test-transient3 [v]
    (let [b (transient [])]
    (conj! b 0)
    (conj! b 1)
    (conj! b 2)
    (persistent! b)))

user> (test-transient3 [1 2 3])
[0 1 2]

for 是否有一些限制?如果是这样,我如何将值从持久向量复制到瞬态?

谢谢。

【问题讨论】:

    标签: clojure


    【解决方案1】:

    瞬态不应该像那样被就地打击。您的最后一个示例仅适用于您不应依赖的实现细节。

    for 不起作用的原因是它是惰性的,并且永远不会执行 conj! 调用,但这不是重点,因为无论如何你都不应该以这种方式处理瞬变。

    您应该使用 conj!,就像使用带有不可变向量的“常规”conj 一样 - 使用返回值。

    您正在尝试做的事情可以这样完成:

    (defn test-transient [v]
      (let [t (transient [])]
        (persistent! (reduce conj! t v))))
    

    【讨论】:

    • 感谢您的回复。但我还是很困惑。在这种情况下,我看不出我对 for 的使用与来自 clojure 网站的示例有很大区别:(defn vrange2 [n] (loop [i 0 v (transient [])] (if (&lt; i n) (recur (inc i) (conj! v i)) (persistent! v))))
    • 那个recur表达式传递了conj的!回到循环中。因为表达式不是这样工作的。
    • 好的,知道了。谢谢和赞赏。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-19
    • 2011-03-13
    • 1970-01-01
    • 2015-11-29
    • 1970-01-01
    相关资源
    最近更新 更多