正确的表达式定义
Correct def for expression
我有这个功能:
(defn get-validator []
(UrlValidator. (into-array ["https"])))
我希望它只被计算一次,在第一次调用时,然后 return 结果。哪种写法更好:
(def get-validator (UrlValidator. (into-array ["https"])))
(def ^:const get-validator (UrlValidator. (into-array ["https"])))
(defonce get-validator (UrlValidator. (into-array ["https"])))
或者有其他更好的方法吗?文档表明 defonce
是正确的,但没有明确说明。
首先,def
设置一个具有给定名称和可选的变量
当命名空间为 loaded/compiled 时,在该 var 中给出“init”值
(注意loading基本没有太大区别
和编译,这就是为什么你不想拥有的原因
def
).
中的副作用
三个版本大体相同,区别如下:
:^const
允许内联这个值;所以这会影响以下
形式,当它们被编译时,可能会提高性能
以下代码
defonce
防止一旦命名空间被再次重新定义 var
重新加载;如果你 def
可变状态,这是最有用的,你
想在重新加载代码后生存下来
无论如何,第一次需要ns,都会执行代码
初始化变量。然后它基本上就不管了(想象一个静态的
属性 在带有静态初始值设定项的 Java class 中)。
综上所述:如果 UrlValidator
有内部状态,你可能仍然是
最好在需要时使用函数创建一个新函数。
另一种方法,假设 UrlValidator.
是参照透明的,是使用 clojure.core/memoize
.
所以
(defn get-validator []
(UrlValidator. (into-array ["https"])))
(def uval (memoize get-validator))
然后在需要验证器时使用 (uval)
。由于记忆,get-validator
只会被调用一次。
这种方法在第一次执行 (uval)
时只会调用一次 UrlValidator.
。所有其他建议将在加载命名空间时调用一次 UrlValidator.
。
我有这个功能:
(defn get-validator []
(UrlValidator. (into-array ["https"])))
我希望它只被计算一次,在第一次调用时,然后 return 结果。哪种写法更好:
(def get-validator (UrlValidator. (into-array ["https"])))
(def ^:const get-validator (UrlValidator. (into-array ["https"])))
(defonce get-validator (UrlValidator. (into-array ["https"])))
或者有其他更好的方法吗?文档表明 defonce
是正确的,但没有明确说明。
首先,def
设置一个具有给定名称和可选的变量
当命名空间为 loaded/compiled 时,在该 var 中给出“init”值
(注意loading基本没有太大区别
和编译,这就是为什么你不想拥有的原因
def
).
三个版本大体相同,区别如下:
:^const
允许内联这个值;所以这会影响以下 形式,当它们被编译时,可能会提高性能 以下代码defonce
防止一旦命名空间被再次重新定义 var 重新加载;如果你def
可变状态,这是最有用的,你 想在重新加载代码后生存下来
无论如何,第一次需要ns,都会执行代码 初始化变量。然后它基本上就不管了(想象一个静态的 属性 在带有静态初始值设定项的 Java class 中)。
综上所述:如果 UrlValidator
有内部状态,你可能仍然是
最好在需要时使用函数创建一个新函数。
另一种方法,假设 UrlValidator.
是参照透明的,是使用 clojure.core/memoize
.
所以
(defn get-validator []
(UrlValidator. (into-array ["https"])))
(def uval (memoize get-validator))
然后在需要验证器时使用 (uval)
。由于记忆,get-validator
只会被调用一次。
这种方法在第一次执行 (uval)
时只会调用一次 UrlValidator.
。所有其他建议将在加载命名空间时调用一次 UrlValidator.
。