Clojure 如何在列表中不使用双引号
我的代码中有以下行:Clojure 如何在列表中不使用双引号,clojure,Clojure,我的代码中有以下行: (spit path (prn-str job-data)) 它做得很好。首先,列表中的每一项都放在双引号之间 ( ":a" ":b" ":a" ) 我想要的预期结果 ( :a :b :a ) 如何达到预期的效果 提前谢谢 我猜工作数据不是你所期望的 user=> (prn-str '(:a :b :c)) "(:a :b :c)\n" 如果您确实有一个包含类似关键字的字符串的列表,并且希望将其转换为关键字,则可以使用 (map (comp keyword
(spit path (prn-str job-data))
它做得很好。首先,列表中的每一项都放在双引号之间
( ":a" ":b" ":a" )
我想要的预期结果
( :a :b :a )
如何达到预期的效果
提前谢谢 我猜工作数据不是你所期望的
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"
发生了什么事
问题不在于项目本身被放在双引号中,而是它们是字符串(与您期望的关键字相反)
,它最终基于,以“读者可以读取对象的方式”打印对象。这意味着字符串是用双引号打印的,否则读者将无法区分字符串和符号,或者无法读取带有空格的字符串。有关Clojure阅读器的更多信息,请参阅
另一方面,它们的目的是“生产供人类消费的产品”,而不是将字符串放在双引号中。这就是为什么您会看到prn str
和println
之间的输出差异
您可以使用类
验证这一点。如果您尝试(>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"
如何改变它
现在寻找可能的解决方案。如果您希望作业数据
包含关键字,则正确的修复程序最有可能修改作业数据
。然而,如果我不知道如何生成工作数据
,我就无法在这里提供太多指导
如果出于某种原因,您无法修改工作数据
(例如,如果它是由您不控制的代码生成的),并且您希望在包含类似关键字字符串的位置编写关键字,那么@maxthoursie的建议可能是您的最佳选择。(假设您可以切换到print
或println
,但这可能会对其他对象的打印方式产生不良影响)
如果作业数据
可能包含关键字字符串以外的对象,则只能在适当时应用该函数
(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))
如果I(println作业数据),则打印时不带双引号。在我看来,prn str似乎在项目上添加了引号。但如果没有prn str,它只打印LazySeq,这更糟。:-)
(defn println-str [& more]
(with-out-str (apply println more)))
(spit path (println-str job-data))