Clojure 函数定义的参数中的双括号是什么意思?

Jac*_*ord 0 clojure

(defn foo [[a] b]
  (println a b))

(foo "one" "two") ; => o two

(foo 1 2) ; => Execution error (UnsupportedOperationException) at user/foo (REPL:1).
          ;    nth not supported on this type: Long
Run Code Online (Sandbox Code Playgroud)

周围的第二对括号在a做什么?

或者,我遇到的一个真实世界的例子

(parser/add-tag! :i18n
  (fn [[k] context]
    (->> k (keyword) (translate (or (:i18n/locale context) :en)))))
Run Code Online (Sandbox Code Playgroud)

Jac*_*ord 6

它是 Clojure 的解构语法。

(defn bar [[a b] c]
  (println a b c))
Run Code Online (Sandbox Code Playgroud)

将从传递给的第一个参数中“拉出”第一个和第二个项目,bar并立即将它们分别分配给变量ab。它在功能上等同于:

(defn bar [vector c]
  (let [a (nth vector 0)  ; assign first item in first parameter to a
        b (nth vector 1)] ; assign second item in first parameter to b
    (println a b c)))     ; c is passed & printed as-is
Run Code Online (Sandbox Code Playgroud)

在你的例子中:

(defn foo [[a] b]
  (println a b))
Run Code Online (Sandbox Code Playgroud)

运行(foo "one" "two")意味着“设置a为第一个项目 in"one"bto "two",然后打印a b

在 Clojure 中,字符串是seq-able,因此[[a]]在这种特定情况下意味着“设置a为字符串的第一个字符"one",即o.

(foo 1 2)失败,因为数字 (Longs)不能进行seq,因此它们不能被解构。


(fn [[k] context] … )将意味着“在传递给此函数的两个参数中,从第一个参数中取出第一项并将其设置为k。第二个参数保持原样。”