Clojure:何时使用记忆,何时使用延迟/强制?

Nik*_*hev 1 clojure

我刚刚开始学习 Clojure 并试图了解两种乍一看非常相同的方法之间的区别。

(def func0 (delay (do 
                    (println "did some work") 
                    100)))
so.core=> (force my-delay2)
did some work
100
so.core=> (force my-delay2)
100
Run Code Online (Sandbox Code Playgroud)
(defn vanilla-func [] (println "did some work") 100)
(def func1 (memoize vanilla-func))
so.core=> (func1)
did some work
100
so.core=> (func1)
100
Run Code Online (Sandbox Code Playgroud)

这两种方法都做某种功能记忆。我错过了什么?

我试图在https://clojuredocs.org/clojure.core/delay & https://clojuredocs.org/clojure.core/memoize上找到解释,但找不到。

cfr*_*ick 6

delay持有一个结果,你必须deref得到结果。 memoize是一个未绑定的缓存,它根据输入参数缓存结果 。例如

user=> (def myinc (memoize (fn [x] (println x) (inc x))))
#'user/myinc
user=> (myinc 1)
1
2
user=> (myinc 1)
2
Run Code Online (Sandbox Code Playgroud)

在您的(无参数)示例中,唯一的区别是您可以直接使用结果(deref不需要)

经典用例delay是稍后需要的东西,这会阻止或延迟启动。或者,如果您想def从编译器中“隐藏”顶级s(例如,它们会产生副作用)。

memoize是一种经典的缓存,如果计算成本高且输入参数集不过量,则最好使用。clojure-verse 中还有其他缓存选项,可以实现更好的配置(例如,它们不是未绑定的)。

  • 与 memoize 不同,“delay”还缓存异常。 (3认同)