在 Clojure 中,是否可以在使用顺序解构时提供默认值?

In Clojure, can a default value be provided while using sequential destructuring?

似乎在关联解构中提供了一个默认值是有据可查的。 https://clojure.org/guides/destructuring

在顺序解构中提供默认值的任何已知方法?

例如:

    (let [[hey you guys] ["do" "re"]]
      (println hey)
      (println you)
      (println guys))

Output:
do
re
nil

您如何为 'guys' 提供默认值?

尝试过

(let [[hey you (or guys "me")] ["do" "re"]]

(let [[hey you #(or % "me")] ["do" "re"]]

的一些变体
(let [[hey you guys :or "me"] ["do" "re"]]

谢谢!

不,我不相信有一种方法可以在非关联解构中提供默认值。

根据您的需求,实现该目标的方法不止一种。最接近您提供的片段的可能是:

(let [input ["do" "re"]
      defaults ["def1" "def2" "def3" "def4"]
      [hey you guys] (concat input (drop (count input) defaults))]
  (println hey you guys)) ;; do re def3

如果您只有第三个参数的默认值,那么您可以使用:

(let [[hey you guys] (conj ["do" "re"] "def3")]
  (println hey you guys)) ;; do re def3

(let [[hey you guys] ["do" "re"]
      guys (or guys "def3")]
  (println hey you guys)) ;; do re def3

您可以在此处找到有关 Clojure 解构的很好的概述:

http://blog.brunobonacci.com/2014/11/16/clojure-complete-guide-to-destructuring/

你可以通过一个简单的功能得到你想要的:

(defn apply-defaults
  [vals defaults]
  (vec (map-indexed
         (fn [idx val-default]
           (or (get vals idx) ; replaces both missing and `nil` values
             val-default))
         defaults)))

结果:

data      => [:a     nil    :c]
defaults  => [:def-a :def-b :def-c :def-d]

(apply-defaults data defaults) => [:a :def-b :c :def-d]

请注意,如果要在输入中保留任何 nil 值,则必须对其进行修改。

如果长度较短,可以这样做:

(let [[hey you guys] (merge defaults values)]
      (println hey)
      (println you)
      (println guys))

Merge 是一个你必须 define/choose 的函数,这取决于你想要的行为,它可能是这两个之一(如前面的答案):

  1. 覆盖 defaults 中存在于 values
  2. 中的值
  3. concat 第一个值缺失