我的代码中有以下行:
(spit path (prn-str job-data))
它确实可以很好地执行一件事,列表中的每个项目都放在双引号之间......
( ":a" ":b" ":a" )
我想要的预期结果
( :a :b :a )
如何得到预期的结果?
提前致谢!
我的代码中有以下行:
(spit path (prn-str job-data))
它确实可以很好地执行一件事,列表中的每个项目都放在双引号之间......
( ":a" ":b" ":a" )
我想要的预期结果
( :a :b :a )
如何得到预期的结果?
提前致谢!
问题不在于这些项目本身被放在双引号中,而是它们是字符串(与您期望的关键字相反)。
prn-str
,它最终基于pr
,以“读者可以阅读对象的方式”打印对象。这意味着字符串打印在双引号中 - 否则阅读器将无法从符号中区分字符串,或者读取其中包含空格的字符串。有关 Clojure 阅读器的更多信息,请参见此处。
println
和print
另一方面,旨在“为人类消费产生输出”,并且不要将字符串放在双引号中。这就是为什么您会看到prn-str
和之间的输出差异println
。
您可以使用 来验证这一点class
。如果您尝试(-> job-data first class)
,答案将是java.lang.String
或clojure.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-data
。job-data
但是,如果不了解更多关于如何制作的信息,我无法在这里提供太多指导。
如果由于某种原因您无法修改job-data
(例如,如果它是由您无法控制的代码生成的)并且您想在包含类似关键字的字符串的任何地方编写关键字,那么@maxthoursie 的建议可能是您最好的选择。(假设您可以切换到print
or 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))
我猜工作数据不是你所期望的。
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"