1

我的代码中有以下行:

(spit path (prn-str job-data))

它确实可以很好地执行一件事,列表中的每个项目都放在双引号之间......

( ":a" ":b" ":a" )

我想要的预期结果

( :a :b :a )

如何得到预期的结果?

提前致谢!

4

2 回答 2

2

发生了什么

问题不在于这些项目本身被放在双引号中,而是它们是字符串(与您期望的关键字相反)。

prn-str,它最终基于pr,以“读者可以阅读对象的方式”打印对象。这意味着字符串打印在双引号中 - 否则阅读器将无法从符号中区分字符串,或者读取其中包含空格的字符串。有关 Clojure 阅读器的更多信息,请参见此处

printlnprint另一方面,旨在“为人类消费产生输出”,并且不要将字符串放在双引号中。这就是为什么您会看到prn-str和之间的输出差异println

您可以使用 来验证这一点class。如果您尝试(-> job-data first class),答案将是java.lang.Stringclojure.lang.Keyword

以下是一些示例,展示了与关键字和字符串一起使用时打印函数的不同行为:

(def str-job-data '(":a" ":b" ":c"))
(def key-job-data '(:a :b :c))

;; `println` prints both keywords and strings without quotes
(with-out-str (println str-job-data)) ;=> "(:a :b :c)\n"
(with-out-str (println key-job-data)) ;=> "(:a :b :c)\n"

;; `prn-str` prints the strings in quotes but the keywords without quotes
(prn-str str-job-data) ;=> "(\":a\" \":b\" \":c\")\n"
(prn-str key-job-data) ;=> "(:a :b :c)\n"

如何改变它

现在寻找可能的解决方案。如果您希望job-data包含关键字,则最有可能修改正确的修复程序job-datajob-data但是,如果不了解更多关于如何制作的信息,我无法在这里提供太多指导。

如果由于某种原因您无法修改job-data(例如,如果它是由您无法控制的代码生成的)并且您想在包含类似关键字的字符串的任何地方编写关键字,那么@maxthoursie 的建议可能是您最好的选择。(假设您可以切换到printor println,但这可能会对其他对象的打印方式产生不良影响)。

(defn keyword-string->keyword [s]
  (keyword (subs s 1)))

(spit path (prn-str (map keyword-string->keyword job-data)))

如果job-data可能包含关键字类字符串以外的对象,则只能在适当时应用该函数。

(defn convert-job-data [obj]
  (if (and (string? obj)
           (= (.charAt obj 0) \:))
    (keyword-string->keyword obj)
    obj))

(spit path (prn-str (map convert-job-data job-data)))

当然,如果您正在编写的文件无论如何都是供人类消费的,并且与阅读器有关的所有这些业务都无关紧要,您可以轻松地制作自己的文件println-str

(defn println-str [& more]
  (with-out-str (apply println more)))

(spit path (println-str job-data))
于 2013-11-10T04:14:33.873 回答
0

我猜工作数据不是你所期望的。

user=> (prn-str '(:a :b :c))
"(:a :b :c)\n"

如果您确实有一个包含看起来像关键字的字符串的列表,并且您想将其转换为关键字,您可以使用类似

 (map (comp keyword #(subs % 1)) '(":a" ":b" ":c"))

它跳过每个元素的 :,然后将其转换为关键字。

user=> (prn-str (map (comp keyword #(subs % 1)) '(":a" ":b" ":c")))
"(:a :b :c)\n"
于 2013-11-09T22:11:12.127 回答