Что означает двойные скобки в параметрах определения функции Clojure? - PullRequest
1 голос
/ 23 февраля 2020
(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

Что делает вторая пара скобок вокруг a?

Или реальный пример , где я с этим столкнулся:

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

1 Ответ

6 голосов
/ 23 февраля 2020

Это синтаксис Clojure для деструктурирования .

(defn bar [[a b] c]
  (println a b c))

"вытянет" первый и второй элементы из первого аргумента, переданного в bar, и немедленно назначит их переменным a и b соответственно. Функционально это эквивалентно:

(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

В вашем примере:

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

Запуск (foo "one" "two") будет означать «установить a для первого элемента в "one" и b до "two", затем выведите a b.

В Clojure строки seq-способны , поэтому [[a]] в данном конкретном случае c означает «set *» 1027 * до первого символа строки "one", то есть o.

(foo 1 2) не удается, потому что числа (Longs) не seq-способны, поэтому они не могут быть destructured.


(fn [[k] context] … ) будет означать "из двух аргументов, переданных в эту функцию, взять первый элемент из первого аргумента и установить его как k. Оставьте второй аргумент как есть. «

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...