将符号转换为“unmangled”字符串

时间:2016-07-18 12:40:43

标签: clojure

我正在做一个数学游戏。为了存储数学问题,我使用以下记录:

(defrecord Question [args operator]
  Object
  (toString [self]
    (apply str (drop-last 2 (interleave args (repeat \space) (repeat operator) (repeat \space))))))

toString“方法”将args和运算符转换为中缀运算符字符串。

我的问题是,当我尝试将函数(如*)转换为字符串时,我得到一个符合Java标准的合格符号名称:

(str *)
"clojure.core$_STAR_@a2a3e7"

我想要的只是将符号字面转换为字符串,因此*函数会产生"*"。我能做的最好的事情是使用从函数符号到字符串的预定义映射;但理想情况下我不需要地图,只是直接生成符号的字符串版本。

这可能吗?

2 个答案:

答案 0 :(得分:3)

您通过使用函数评估'*可以获得的符号令您感到困惑,您可以通过评估*来获得:

'*
;;=> *

*
;;=> #function[clojure.core/*]

当然,'*并不是获取符号*的唯一方法。您可以使用等效的quote特殊表单,也可以使用symbol函数从字符串创建符号,或者您可以执行其他操作,而不是使用'阅读器宏:

(quote *)
;;=> *

(symbol "*")
;;=> *

如果将符号转换为字符串,则会返回一个字符串,该字符串由该符号的名称(如果存在,名称空间)组成。如果将函数转换为字符串,则返回对象的默认Java字符串表示形式:其类的名称,后跟@字符及其位置的十六进制表示形式在记忆中:

(str '*)
;;=> "*"

(str *)
;;=> "clojure.core$_STAR_@a2a3e7"

因此,如果您使用函数 Question创建* operator,然后尝试将函数转换为一个字符串,你得到这个:

(str (->Question [4 2] *))
;;=> "4 clojure.core$_STAR_@a2a3e7 2 "

另一方面,如果您使用符号 Question作为*创建operator,那么您将获得此信息:< / p>

(str (->Question [4 2] '*))
;;=> "4 * 2 "

给定一个符号,您可以使用resolve将其解析为var,然后使用deref获取该值:

@(resolve '*)
;;=> #function[clojure.core/*]
但是,你不能通过另一种方式(从功能到符号)。有关详细信息,请参阅this question的答案。

答案 1 :(得分:-1)

幸运/不幸的是,我在发布这个问题后立即意识到了答案:宏。

(defmacro sym->string [sym]
  (str sym))

(sym->string *)
"*"

对不起,我想我还不太清醒。

这实际上是错误的:请参阅下面的评论。