【问题标题】:What is the idiomatic way in Clojure to pass a check if one of the parameters is nil?Clojure 中通过检查参数之一是否为 nil 的惯用方式是什么?
【发布时间】:2021-08-31 13:30:18
【问题描述】:

我有一个验证多个输入的函数。

其中一个验证检查 time1 和 time2 之间的间隔是否小于 120 秒。

get-time2 函数从数据库中返回:time 的值。但是这个值可能是nil。目前,这稍后会在 calculate-time-diff 函数中带来 NullPointerException。

如果interval-validation? 的第二个参数是nil,那么使interval-validation? 检查通过的惯用方法是什么?

(defn validate-input [{:keys [time]}]
  (let [error {:errors []}
        add-error #(update %1 :errors conj %2)]
    (cond-> errors
      (validation1) (add-error "err1")
      (interval-violation? time1 (get-time2 3)) (add-error "err2"))))
(defn get-time2 [index]
  (:time (db/get-input! index)))
(defn interval-violation? [time1 time2]
  (let [time-diff (calculate-time-diff time1 time2)]
    (< time-diff 120)))

这是一个惯用的解决方案吗?

(defn interval-violation? [time1 time2] 
  (when (and time1 time2) (< (calculate-time-diff time1 time2) 120)))

【问题讨论】:

  • 如果get-time2 函数返回nil,你希望发生什么?最好的答案通常是抛出异常。如果您只想忽略任何nil 值,只需添加一个if 语句以在一个时间值为nil 时始终返回false。另外,你的意思是get-timeget-time2?。
  • 如果 get-time2 返回 nil,我希望 interval-violation? 不调用 calculate-time-diff 并简单地返回 false。 (是的,我的意思是get-time2,谢谢)。
  • 在谓词上实际返回布尔值(以 ? 结尾)是不成文的法律 - 因此,如果您想遵循此规则,请将您的 when 包装在布尔调用中。使用 when+and 很好 - 但请注意,如果您想严格控制 nil 输入,这对 false 也没有任何作用(这里很可能很好)...

标签: clojure


【解决方案1】:

我会使用some?。如果不是 nil,则返回 true。与nil?相反


(defn interval-violation? [time1 time2]
  (if
    (some? time2)
    (let [time-diff (calculate-time-diff time1 time2)]
      (< time-diff 120))
    ()) ;what happens when time2 is nil goes here.

或者,您可以将 get-time2 更改为不返回 nil。 get可以在没有找到key时设置一个默认值。

(defn get-time2 [index]
  (get (db/get-input! index) :time 0)) ;value if not found goes last

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-08
    • 2016-04-09
    • 2011-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多