Каким образом можно преобразовать ключевое слово clojure с именами в строку?
Когда используется функция name
, она правильно возвращает имя ключевого слова в виде строки, например:
(name :k) => "k"
Проблема возникает при использовании name
для ключевого слова с именами, например:
(name :n/k) => "k"
Я могу использовать функцию namespace
, чтобы правильно получить строку, которую я ищу:
(str (namespace :n/k) "/" (name :n/k)) => "n/k"
Но по какой-то причине я чувствую, что должен быть лучший способ получить полностью соответствующую строку.
Каким будет лучший способ сделать это?
Ответы
Ответ 1
Ключевые слова фактически хранят символ с тем же пространством имен и именем в общедоступном конечном поле и генерируют их строковые представления, добавляя двоеточие в строковое представление этого символа. Таким образом, мы можем просто запросить символ для того же самого и не добавить двоеточие:
(str (.-sym :foo/bar))
;= "foo/bar"
Ответ 2
Ваш подход - лучший способ сделать это; это сложно, потому что преобразование ключевого слова с именами в строку является необычной целью, а не то, что вы ожидаете делать регулярно. Вы можете написать его, не повторяя ключевое слово, если хотите:
(string/join "/" ((juxt namespace name) k))
Ответ 3
(subs (str :foo/k) 1)
;=> "foo/k"
Ответ 4
Основываясь на реализации 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)))