【问题标题】:In Clojure, how can I branch logic depending on which keys are passed into a function?在 Clojure 中,如何根据传递给函数的键来分支逻辑?
【发布时间】:2015-09-21 22:02:56
【问题描述】:

我有一个函数需要根据提供的键调用稍微不同的逻辑。现在我正在使用这种丑陋的“嵌套如果”结构。有人可以告诉我一个更好、更清洁的方法吗?

(defn myfunc
  "Do different things depending on which keys are given."
  [{:keys [a b c]}]
  ;; If (myfunc {:a})
  (if (not (nil? a))
    (do-a)
    ;; If (myfunc {:b})
    (if (not (nil? b))
      (do-b)
      ;; If (myfunc {:c})
      (if (not (nil? c))
        (do-c)
        ;; If none of the above keys are available, do d
        (do-d)))))

我可以使用(contains? ...),但是我不必在签名中指定密钥,它并没有真正改善嵌套结构。

理想情况下,我可以这样做:

(defn myfunc
  "Do different things depending on which keys are given."
  [{:keys [a b c]}]
  (if (two-or-more-of [a b c])
      (some-error)
      (with
        :a (do-a arg1)
        :b (do-b arg2)
        :c (do-c arg1 arg2)
        else (do-d))))

注意:我的宏不够好,无法编写宏,但如果这是正确的答案并且有人想要,我会采用其他人的 =)

【问题讨论】:

    标签: clojure


    【解决方案1】:

    无需编写宏,clojure 为您准备了一个。使用cond 摆脱嵌套的if

    (defn myfunc
      [{:keys [a b c]}]
      (cond (two-or-more-of [a b c]) (some-error)
            (not (nil? a)) (do-a)
            (not (nil? b)) (do-b)
            (not (nil? c)) (do-c)
            :else (do-d)))
    

    【讨论】:

      【解决方案2】:

      我还没有测试过这个,但我认为它应该可以工作。你也可以用更接近你最初想法的方式来做。

      (defn myfunc
        [{:keys [a b c]}]
        (if (two-or-more-of [a b c])
          (some-error)
          (condp = (some identity [a b c])
            a (do-a)
            b (do-b)
            c (do-c)
            (do-d)))) ; default
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-08-03
        • 2021-12-30
        • 1970-01-01
        • 2020-09-07
        • 1970-01-01
        • 2022-11-30
        相关资源
        最近更新 更多