clojure - проблема разрушения карты внутри макроса
Я новичок в уловке, поэтому, пожалуйста, потерпите меня.
Пишем макрос так:
`(let [query# (:query-params ~'+compojure-api-request+)
options# (select-keys query# [:sort-by :from :to])])
Первая строка let
блок разрушает query-params
от http request
- которая производит эту структуру:
{sort-by billing-account/name, from 0, to 10, payment-due , payment-method , search }
И проблема со второй строкой - она возвращает пустую карту, когда я использую select-keys
Однако, когда я говорю, например, (first query#)
- вывод выглядит так: [sort-by billing-account/name]
Может ли кто-нибудь объяснить, почему select-keys
не работает?
PS пробовал (get query# :from) & (:from query#)
- там тоже не повезло.
UPD
Ключи были строками, а не ключевыми словами - поэтому использование строк в качестве ключей работает просто отлично.
2 ответа
Кстати, вы также можете деструктурировать строковые ключи :strs
:
(let [m {"sort-by" "billing-account/name",
"from" "0",
"to" "10",
"payment-due" nil,
"payment-method", "search"}
{:strs [sort-by from to payment-due payment-method]} m]
(println sort-by from to payment-due payment-method))
;;=> billing-account/name 0 10 nil search
См. https://clojure.org/guides/destructuring для полного описания синтаксиса деструктурирования.
Я думаю, что вас смущают различия между ключевыми словами, символами и строками. В своем комментарии вы говорите, что они являются символами, но при редактировании вы говорите, что они являются строками.
Вы должны прочитать разницу:
- в Clojure, почему есть строки, ключевые слова и символы?
- Почему Clojure имеет "ключевые слова" в дополнение к "символам"?
Идиоматическая вещь - обычно предпочитать использовать ключевые слова в качестве ключей карты, хотя вещи, которые приходят из интернета (json, http заголовки и т. Д.), Иногда являются строками.
Чтобы ответить на ваш вопрос напрямую, ключи были переданы select-keys
должны быть равны (используя =
функции) к тем, что на карте, поэтому в этом случае они должны быть одного типа.
;; For example
(select-keys {'foo 1 'bar 2} ['foo]) ;=> {foo 1}
(select-keys {:foo 1 :bar 2} [:foo]) ;=> {:foo 1}
(select-keys {"foo" 1 "bar" 2} ["foo"]) ;=> {"foo" 1}
Также я подвергаю сомнению необходимость того, чтобы это был макрос, есть ли причина, по которой простая функция не будет работать?