简体   繁体   English

将命名空间的clojure关键字转换为字符串的正确方法是什么?

[英]What is the right way to convert a namespaced clojure keyword to string?

When the name function is used it correctly returns the name of a keyword as a String, as in: 使用name函数时,它会正确地将关键字的名称作为String返回,如下所示:

(name :k) ; => "k"

A problem exists when using name on a namespaced keyword such as: 在命名空间关键字上使用name时存在问题,例如:

(name :n/k) ; => "k"

I can use the namespace function to correctly obtain the string I'm looking for: 我可以使用namespace函数来正确获取我正在寻找的字符串:

(str (namespace :n/k) "/" (name :n/k)) ; => "n/k"

But for some reason I feel there should be a better way to obtain the fully qualified string. 但出于某种原因,我觉得应该有更好的方法来获得完全限定的字符串。

What would be the best way to do it? 最好的方法是什么?

Your approach is the best way to do it; 你的方法是最好的方法; it's only hard because converting a namespaced keyword to a string is an uncommon goal, and not something you'd expect to do regularly. 这很难,因为将命名空间关键字转换为字符串是一个不常见的目标,而不是您经常要做的事情。 You could write it without repeating the keyword, if you wanted: 如果您愿意,可以在不重复关键字的情况下编写它:

(string/join "/" ((juxt namespace name) k))

Keywords actually store a symbol with the same namespace and name in a public final field and generate their string representations by prepending a colon to the string representation of that symbol. 关键字实际上在公共final字段中存储具有相同名称空间和名称的符号,并通过在该符号的字符串表示前面添加冒号来生成字符串表示。 So, we can simply ask the symbol for the same and not prepend the colon: 所以,我们可以简单地询问符号,而不是前面的冒号:

(str (.-sym :foo/bar))
;= "foo/bar"
(subs (str :foo/k) 1)
;=> "foo/k"

Based on the implementation of name : 基于name的实现:

user=> (source name)
(defn name
  "Returns the name String of a string, symbol or keyword."
  {:tag String
   :added "1.0"
   :static true}
  [x]
  (if (string? x) x (. ^clojure.lang.Named x (getName))))
nil
user=>

And given that the clojure.lang.Named interface has a getNamespace method: 鉴于clojure.lang.Named接口有一个getNamespace方法:

https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Named.java https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/Named.java

So you can do this: 所以你可以这样做:

(defn full-name [k] (str (.getNamespace k) "/" (.getName k)))

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

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