在Clojure中构建字符串的麻烦

Aki*_*dar 4 clojure

[这可能看起来像我的问题是Compojure,但它不是 - 它与Clojure一起]

在这个看似简单的问题上,我一直在拔头发 - 但我无处可去.

我正在使用Compojure(Clojure的轻量级Web框架),我想生成一个显示我在PostgreSQL数据库中的待办事项列表的网页.

下面的代码片段(省略了数据库连接,查询等 - 但不需要该部分,因为特定问题是生成的HTML在<body>和</ body>标记之间没有显示任何内容).

作为测试,我尝试在对main-layout的调用中对字符串进行硬编码,如下所示:(html(main-layout"Aki's Todos""Haircut <br> Study Clojure <br>在Stackoverfolw上回答问题")) - 它工作正常.

所以真正的问题是我不相信我知道如何在Clojure中建立一个字符串.不是惯用的方式,也不是通过调用Java的StringBuilder - 正如我在下面的代码中尝试做的那样.

虚拟啤酒,对任何能够解决它的人来说都是一个很大的支持!非常感谢!

================================================== ===========


;The master template (a very simple POC for now, but can expand on it later)

(defn main-layout
  "This is one of the html layouts for the pages assets - just like a master page"
  [title body]
  (html
    [:html
    [:head
      [:title title]
      (include-js "todos.js")
      (include-css "todos.css")]
    [:body body]]))


(defn show-all-todos 
  "This function will generate the todos HTML table and call the layout function"
  []
  (let [rs (select-all-todos)
       sbHTML (new StringBuilder)]
    (for [rec rs]
      (.append sbHTML (str rec "<br><br>"))) 
    (html (main-layout "Aki's Todos" (.toString sbHTML)))))
Run Code Online (Sandbox Code Playgroud)

================================================== ===========

同样,结果是一个网页,但身体标签之间没有任何内容.如果我使用println语句替换for循环中的代码,并将代码指向repl - 忘记网页内容(即调用main-layout),结果集将被打印 - 但是 - 问题在于构建字符串.

再次感谢.

〜亚希

Bri*_*per 6

for是懒惰的,在你的功能中,它永远不会被评估.更改fordoseq.

user> (let [rs ["foo" "bar"] 
            sbHTML (new StringBuilder)]
        (for [rec rs]
          (.append sbHTML (str rec "<br><br>")))
        (.toString sbHTML))
""
user> (let [rs ["foo" "bar"] 
            sbHTML (new StringBuilder)]
        (doseq [rec rs]
          (.append sbHTML (str rec "<br><br>")))
        (.toString sbHTML))
"foo<br><br>bar<br><br>"
Run Code Online (Sandbox Code Playgroud)

您也可以使用reduceinterpose,或clojure.string/join来自clojure.string,或者可能使用其他一些选项.

user> (let [rs ["foo" "bar"]]
            (reduce str (interpose "<br><br>" rs)))
"foo<br><br>bar"
user> (require 'clojure.string)
nil
user> (let [rs ["foo" "bar"]]
            (clojure.string/join "<br><br>" rs))
"foo<br><br>bar"
Run Code Online (Sandbox Code Playgroud)