(constantly x) 与 (fn [& _] x) 有何不同?
How does (constantly x) differ from (fn [& _] x)?
我正在使用多种方法来提供不同的功能,具体取决于 "mode" 我的项目 运行 在(它是一个 yada api 服务器,并且应该能够 运行 在 :dev
、:prod
模式等)。
我正在使用 mount/defstate
提供关键字:
(defstate mode :start :dev)
当我使用 (constantly mode)
发送时出现错误,但是当我使用 (fn [& _] mode)
发送时它似乎有效。
这两种形式不一样吗?或者它们的评估方式(或时间)是否存在细微差别?
在 mount 中,如果您尚未开始状态,则它们的值为 DerefableState
个对象。
通过调用 constantly,您首先计算 mode
的值,然后使用该值调用 constantly
函数。这意味着当您调用 constantly
的结果时,它总是 return constantly 的参数,尽管您已经更改了它。如果您在调用 constantly
之前尚未启动您的状态,那么它将存储 DerefableObject
.
另一方面,使用 (fn [& _] mode)
时,每次调用函数时都会计算 mode
var 的值。如果你还没有开始你的状态那么它也会 return 一个 DerefableState
但如果你已经开始那么结果将是预期的关键字。
一个简单的解决方案是将调度函数也置于状态中。
(defstate dispatch :start (constantly state))
我认为对于另一种解释,您可以使用副作用来突出差异。
比较:
(def const-f (constantly (println "Hello!")))
Hello!
=> #'user/const-f
(def fn-f (fn [] (println "World!")))
=> #'user/fn-f
只执行第一个 def
会导致打印 Hello!
,因为立即评估 constantly
的主体。然而,第二个 def
不打印任何内容,因为 fn
的主体未被评估。
尽管打电话给他们时:
(const-f)
=> nil ; Prints nothing. Just evaluates to what println returned
(fn-f)
World! ; Prints now,
=> nil ; then returns what println evaluates to
constantly
不是宏,因此必须首先评估它的参数。 fn
但是 是 一个宏,因此它在评估其参数之前运行。
我正在使用多种方法来提供不同的功能,具体取决于 "mode" 我的项目 运行 在(它是一个 yada api 服务器,并且应该能够 运行 在 :dev
、:prod
模式等)。
我正在使用 mount/defstate
提供关键字:
(defstate mode :start :dev)
当我使用 (constantly mode)
发送时出现错误,但是当我使用 (fn [& _] mode)
发送时它似乎有效。
这两种形式不一样吗?或者它们的评估方式(或时间)是否存在细微差别?
在 mount 中,如果您尚未开始状态,则它们的值为 DerefableState
个对象。
通过调用 constantly,您首先计算 mode
的值,然后使用该值调用 constantly
函数。这意味着当您调用 constantly
的结果时,它总是 return constantly 的参数,尽管您已经更改了它。如果您在调用 constantly
之前尚未启动您的状态,那么它将存储 DerefableObject
.
另一方面,使用 (fn [& _] mode)
时,每次调用函数时都会计算 mode
var 的值。如果你还没有开始你的状态那么它也会 return 一个 DerefableState
但如果你已经开始那么结果将是预期的关键字。
一个简单的解决方案是将调度函数也置于状态中。
(defstate dispatch :start (constantly state))
我认为对于另一种解释,您可以使用副作用来突出差异。
比较:
(def const-f (constantly (println "Hello!")))
Hello!
=> #'user/const-f
(def fn-f (fn [] (println "World!")))
=> #'user/fn-f
只执行第一个 def
会导致打印 Hello!
,因为立即评估 constantly
的主体。然而,第二个 def
不打印任何内容,因为 fn
的主体未被评估。
尽管打电话给他们时:
(const-f)
=> nil ; Prints nothing. Just evaluates to what println returned
(fn-f)
World! ; Prints now,
=> nil ; then returns what println evaluates to
constantly
不是宏,因此必须首先评估它的参数。 fn
但是 是 一个宏,因此它在评估其参数之前运行。