5

想请教一下……

什么,“常量值的 var 或 ref/atom/agent?”,我要问吗?当然,我确实将 vars 用于常量值。

但是我一直想知道当值的行为类似于常量时应该使用哪一个,但它们应该在运行时分配,而不是在编译时(读取代码时)。

例如,考虑一些写在用户配置文件中的 java 属性。它们应该在运行时分配,因为数据不在代码中。但是它们也应该在读取数据之前定义,因为其他代码引用它们。

在这种情况下,

我什么时候使用'var's?:

  • 我定义'var's,或者只是声明'var's(如果可以的话)。
  • 然后我通过读取选项文件的函数再次重新定义那些'var'。
  • 但是覆盖'var'感觉很糟糕,或者定义'var'内部函数感觉很奇怪。

我什么时候使用 ref/atom/agent?:

  • 我将 ref/atom/agents 分配给 'var's。
  • 然后我通过读取选项文件的函数更新这些 ref/atom/agents。
  • 但由于这些值在整个程序中使用,所以我担心它们的成本。
  • ...并且使用太多 @ 宏有点烦人。

我不知道我应该用什么。

在这些情况下你用什么?

'var's? '参考/原子/代理?甚至是“延迟”?

提前致谢。

4

1 回答 1

2

如果您正在学习的所有或一组“常量”可以在一个时间点学习,那么我们将它们称为“属性”。

让我们做一个“吸引他们”的配置:

(defn resource [path]
  (when path
    (-> (Thread/currentThread) .getContextClassLoader (.getResource path))))

(def props
  (edn/read-string 
    (slurp (io/file (resource (System/getProperty "your.conf"))))))

(defn conf [& path]                  ;; e.g. (conf :db :uri)
  (get-in props (vec path)))

您的属性(例如“常量”)文件“your.conf”将位于以下行中:

{:db
    {:uri "datomic:mem://dbname"
     :other-property 42}

 :rabbit
        {:host "192.168.1.17"
         :port 5672
         :exchange "xyz-exchange"
         :queue "zq"
         :exchange.type "direct"
         :vhost "/some-broker"
         :username "user"
         :password "strong"}}

然后稍后在您的程序/其他名称空间中,您可以访问所有这些属性:

(conf :db :uri)               ;; will "constant"ly return "datomic:mem://dbname"
(conf :rabbit :host)          ;; will "constant"ly return "192.168.1.17"
(conf :db :other-property)    ;; will "constant"ly return 42

在“现实生活”中,上面的“props”变量可能会检查“-D”路径,具有默认值并处理异常,但为了说明这一点,它有点简化。

于 2013-11-15T15:52:58.860 回答