【问题标题】:Unused args in watcher function观察者函数中未使用的参数
【发布时间】:2015-04-15 21:42:46
【问题描述】:

这是来自Clojure Programming的代码示例

(def history (atom ()))
(defn log->list
  [dest-atom key source old new]
  (when (not= old new)
    (swap! dest-atom conj new)))
(def sarah (atom {:name "Sarah" :age 25}))
(add-watch sarah :record (partial log->list history))
(swap! sarah update-in [:age] inc)
(swap! sarah identity)
(pprint @history)

log->list 函数有两个永远不会被使用的参数 keysource。他们来这里做什么?

【问题讨论】:

    标签: concurrency clojure


    【解决方案1】:

    关键是用于稍后删除它的标签:

    (remove-watch reference key)
    

    如果随后将密钥传递给监视函数,则它可以在触发后稍后将其自身删除。尽管您也可以通过事先约定键名来构建它,但是拥有此功能可以使事情变得更加优雅。

    【讨论】:

    • 这很奇怪,为什么key必须出现在函数本身?
    • 使用_ 会比较礼貌
    【解决方案2】:

    来自 add-watch 上的文档字符串:

    将监视函数添加到代理/原子/var/ref 引用。手表 fn 必须是 4 个参数的 fn:键、引用、它的旧状态、它的 新状态...

    因为我们要在原子上添加一个监视,log->list 需要是一个 4 元函数。我们将获得键、引用、旧值和新值。即使我们只使用旧值和新值,我们也需要在函数中有 4 个 args,以便它具有正确的数量。

    在 Clojure 中,在函数定义中使用下划线代替未使用的参数来表明它未使用并减少视觉噪音通常是惯用的。但是在这种情况下,我认为保留未使用的变量并命名它们可以使正在发生的事情更清楚,并且可以在将来在必要时更容易地对其进行修改。这一点特别重要,因为我们需要保持这个函数的数量完全相同,以便它与 add-watch 一起工作。在书中,我倾向于这个选项。

    在实际代码中它是边界线,我可以在下划线和命名参数上采用任何一种方式。我的选择可能取决于上下文以及在清晰和简洁之间取得适当平衡的任何内容。

    【讨论】:

      猜你喜欢
      • 2019-11-02
      • 2018-05-16
      • 1970-01-01
      • 1970-01-01
      • 2020-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-22
      • 2018-09-28
      相关资源
      最近更新 更多