17

使用该name函数时,它会正确地将关键字名称作为字符串返回,如下所示:

(name :k) ; => "k"

在命名空间关键字上使用时存在问题,name例如:

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

我可以使用该namespace函数正确获取我要查找的字符串:

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

但出于某种原因,我觉得应该有更好的方法来获得完全合格的字符串。

最好的方法是什么?

4

4 回答 4

10

关键字实际上将具有相同命名空间和名称的符号存储在公共 final 字段中,并通过在该符号的字符串表示之前添加一个冒号来生成它们的字符串表示。因此,我们可以简单地询问相同的符号,而不是在冒号前面:

(str (.-sym :foo/bar))
;= "foo/bar"
于 2013-05-17T00:45:19.353 回答
7

你的方法是最好的方法;这很困难,因为将命名空间关键字转换为字符串是一个不常见的目标,而不是您希望经常做的事情。如果需要,您可以在不重复关键字的情况下编写它:

(string/join "/" ((juxt namespace name) k))
于 2013-05-16T20:06:01.763 回答
6
(subs (str :foo/k) 1)
;=> "foo/k"
于 2013-05-16T19:33:38.250 回答
0

基于以下实施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=>

并且鉴于clojure.lang.Named接口有一个getNamespace方法:

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

所以你可以这样做:

(defn full-name [k] (str (.getNamespace k) "/" (.getName k)))
于 2013-05-16T20:22:34.697 回答