В Clojure 1.2 вы можете деструктурировать аргумент rest
так же, как если бы вы деструктурировали карту. Это означает, что вы можете использовать именованные непозиционные ключевые аргументы. Вот пример:
user> (defn blah [& {:keys [key1 key2 key3]}] (str key1 key2 key3))
#'user/blah
user> (blah :key1 "Hai" :key2 " there" :key3 10)
"Hai there10"
user> (blah :key1 "Hai" :key2 " there")
"Hai there"
user> (defn blah [& {:keys [key1 key2 key3] :as everything}] everything)
#'user/blah
user> (blah :key1 "Hai" :key2 " there")
{:key2 " there", :key1 "Hai"}
Все, что вы можете сделать при деструктурировании карты Clojure, можно сделать в списке аргументов функции, как показано выше. Включая использование: или для определения значений по умолчанию для аргументов, таких как:
user> (defn blah [& {:keys [key1 key2 key3] :or {key3 10}}] (str key1 key2 key3))
#'user/blah
user> (blah :key1 "Hai" :key2 " there")
"Hai there10"
Но это в Clojure 1.2. Кроме того, в более старых версиях вы можете сделать это, чтобы симулировать то же самое:
user> (defn blah [& rest] (let [{:keys [key1 key2 key3] :or {key3 10}} (apply hash-map rest)] (str key1 key2 key3)))
#'user/blah
user> (blah :key1 "Hai" :key2 " there")
"Hai there10"
и это обычно работает так же.
И у вас также могут быть позиционные аргументы, предшествующие аргументам ключевого слова:
user> (defn blah [x y & {:keys [key1 key2 key3] :or {key3 10}}] (str x y key1 key2 key3))
#'user/blah
user> (blah "x" "Y" :key1 "Hai" :key2 " there")
"xYHai there10"
Они не являются обязательными и должны быть предоставлены.
Вы можете фактически уничтожить аргумент rest
так же, как и любую коллекцию Clojure.
user> (defn blah [& [one two & more]] (str one two "and the rest: " more))
#'user/blah
user> (blah 1 2 "ressssssst")
"12and the rest: (\"ressssssst\")"
Вы можете делать такие вещи даже в Clojure 1.1. Деструктуризация в стиле карты только для аргументов ключевых слов появилась в версии 1.2.