从数字创建关键字

Create a keyword from a number

tl;博士

如何从 ClojureScript 中的数字导出关键字:

(keyword 22)
;;=> :22 but in fact returns nil.

背景

在我的 ClojureScript/Hoplon 应用程序中,我通过 cljs-http 发出 HTTP 请求。我收到的部分回复如下所示:

{:companies
  {:22 {:description ... } ; A company.
   :64 {:description ... }
   ...                    }
{:offers
  [{:description ... } ; An offer.
   {:description ... }
   ...                ]

:offers 后面的向量中的每个报价都有一个 :companyId,代表 :companies 中的一个键。一收到回复,我就reset!一个cell(类似于原子)query.

现在,我想遍历每个报价并调用函数 offer-tpl 来创建相应的 HTML。为此,offer-tpl 需要报价本身以及相关公司:

(for [offer (:offers @query)]
  (offer-tpl offer (get-in @query [:companies (keyword (:companyId offer))]))))))

尽管这肯定可以做得更优雅(非常感谢建议),但 get-in 不起作用。 (:companyId offer) returns 一个数字(例如 22)但是 (keyword (:companyId offer)) returns nil。调用 (keyword (str (:companyId offer))) 可以解决问题,但是没有其他方法可以做到这一点吗?

(keyword "22")(keyword (str 22)) returns :22

您得到 :22 的原因可能是因为 JSON 翻译的 keywordize-keys 选项。例如:

cljs-http 默认为 jsonp 的 keywordize-keys: https://github.com/r0man/cljs-http/blob/1fb899d3f9c5728521786432b5f6c36d1d7a1452/src/cljs_http/core.cljs#L115 但是在这种情况下,您可以(并且应该)传递一个标志来禁用关键字化。

并非 JSON 中的所有键都适合 Clojure 关键字化。例如,JSON 键中的空格有效,但在 Clojure 中无效。

请注意,数字关键字可能不正确。 https://clojuredocs.org/clojure.core/keyword#example-542692cec026201cdc326d70 似乎该警告已从当前的 Clojure 网站中删除,所以也许这意味着什么,但我不确定是什么。

http://clojure.org/reference/reader 目前声明

Keywords - Keywords are like symbols, except: They can and must begin with a colon, e.g. :fred. They cannot contain '.' or name classes. Like symbols, they can contain a namespace, :person/name A keyword that begins with two colons is resolved in the current namespace: In the user namespace, ::rect is read as :user/rect

还有那个

Symbols begin with a non-numeric character and can contain alphanumeric.

此关键字定义不包括 :22:with spaces

关键字函数 returns 是无效输入的结果,但这不是背书,只是因为检查错误输入会在 Clojure 的核心部分造成性能开销。

简而言之,并非所有 JSON 键都会转换为关键字,因此您应该避免使用 keywordize-keys 除非您知道键空间 and/or 这样做提供了一些便利。