对于常量值,使用var、ref/atom或agent哪种更好?

5

我想谦虚地询问一下...

对于常量值,"使用var还是ref/atom/agent?",我该怎么办呢?

当然,我会使用vars来表示常量值。

但我一直在想,当这些值表现得像常量但需要在运行时而不是编译时(代码读取时)被赋值时,我应该使用哪个呢?

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

在这种情况下,

我什么时候使用'var':

  • 我定义'var',或者只声明'var'(当可以这样做时)。
  • 然后我通过读取选项文件的函数重新定义这些'var'。
  • 但是覆盖'var'感觉很糟糕,或者在函数内部定义'var'感觉很奇怪。

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

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

我不知道该用什么。

你在这种情况下使用什么?

'var'?'ref/atom/agent'?甚至是'delay'?

提前致谢。


为什么不在程序开始时同步定义变量呢?这样,在其他地方就不需要覆盖该变量了。另一方面,如果你厌烦到处写@my-var,你可以定义一个包装函数,它返回@my-var - hsestupin
谢谢您的回答。我如何同步定义我的变量?我不认为我理解您的意思。我认为变量不是同步的东西。您是指将引用分配给变量并重置(更新)引用以进行初始化吗? - Bak Yeon O
1
我的意思是,在你的命名空间 ns.with-const 中,第一行代码是 (def my-const (some-computations))。因此,在这个表达式被求值之前,所有试图使用或要求 ns.with-const 的命名空间都不会开始评估它们自己的代码。在这个模型中没有竞争条件。当你的常量被计算出来时,它就变成了定义,并且一切都正常工作。希望这个解释有意义。 - hsestupin
看起来是个聪明的想法-我应该试一试!也许它不能被预编译,但在大多数情况下它会很有帮助。谢谢! - Bak Yeon O
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”路径,具有默认值并处理异常,但为了说明重点,这里做了简化。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接