简体   繁体   English

clojure-破坏宏内的映射的麻烦

[英]clojure - trouble destructing map inside macro

I'm a newbie in clojure, so please bear with me. 我是Clojure的新手,所以请多多包涵。

Writing a macro as so: 这样编写宏:

 `(let [query#   (:query-params ~'+compojure-api-request+)
        options# (select-keys query# [:sort-by :from :to])])

First line of the let block destructures a query-params from http request - which produces this structure: let块的第一行从http request解构了一个query-params -产生了以下结构:

{sort-by billing-account/name, from 0, to 10, payment-due , payment-method , search }

And the trouble is with the second line - it returns an empty map when I use select-keys , however when I say for example (first query#) - the output looks like this: [sort-by billing-account/name] 问题出在第二行–当我使用select-keys ,它返回一个空的映射,但是当我说(first query#) ,输出看起来像这样: [sort-by billing-account/name]

Could anyone please explain why the select-keys does not work? 谁能解释一下为什么select-keys不起作用?

PS Tried (get query# :from) & (:from query#) - no luck there as well. PS尝试过(get query# :from) & (:from query#) -那里也没有运气。

UPD UPD

Keys were strings, not keywords - therefore using strings as keys works just fine. 键是字符串,而不是关键字-因此,将字符串用作键就可以了。

By the way, you can also destructure string keys with :strs : 顺便说一句,您也可以使用: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     

See https://clojure.org/guides/destructuring for a full description of the destructuring syntax. 有关解构语法的完整说明,请参见https://clojure.org/guides/destructuring

I think you are confused by the differences between keywords, symbols and strings. 我认为关键字,符号和字符串之间的差异会让您感到困惑。 In your comment you say that they're symbols, but in your edit you say they're strings. 在您的评论中,您说它们是符号,但在编辑中,您说它们是字符串。

You should read up on the difference: 您应该阅读其中的区别:

The idiomatic thing is to usually prefer using keywords as map keys, although stuff that comes from the internet (json, http headers, etc) is sometimes all strings. 习惯用法是通常更喜欢使用关键字作为映射键,尽管来自互联网的内容(json,http标头等)有时全都是字符串。

To answer your question directly, the keys passed to select-keys need to be equal (using the = function) to the ones in the map, so in this case they need to be the same type. 为了直接回答您的问题,传递给select-keys必须与映射中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}

Also I question the need for this to be a macro, is there a reason that a plain function won't work? 我也质疑是否需要将此作为宏,是否有一个普通函数无法正常工作的原因?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM