线程上的Clojure错误:java.lang.IllegalArgumentException:键必须是整数

时间:2012-09-02 06:52:02

标签: clojure

我对两件事情感到困惑。一,错误信息本身。第二,这个代码旋转了这么多线程的事实。我认为它会激活2或3个线程以响应单个请求,但是当我在localhost上运行它并指向我的浏览器时(仅一次)它会旋转40个线程。不可否认,我正在使用Chrome,后者在后台发送3个请求,原因有各种复杂的原因,Google将其视为“功能”(速度)。

这个错误是什么意思?

Exception in thread "Thread-39" java.lang.IllegalArgumentException: Key must be integer
at clojure.lang.APersistentVector.invoke(APersistentVector.java:250)
at serve_pages_from_memory.core$listen_and_respond$fn__51.invoke(core.clj:30)
at clojure.lang.AFn.run(AFn.java:24)
at java.lang.Thread.run(Thread.java:680)

我之前在StackOverflow上已经讨论过类似的错误,但是我看不出它们如何与我的问题相关联:

clojure filter map by keys

我正在尝试构建一个为页面提供服务的简单应用。我这样做主要是为了测试我自己对Clojure的了解。以下是大部分代码:

(defn start-thread [f]
(doto (new Thread f) (.start)))

(defn serve-page [wrt]
(let [content-length (count page-string)] 
(. wrt println "HTTP/1.1 200 OK")
(. wrt println "Content-Type: text/html; charset=UTF-8")
(. wrt println "Connection: Keep-Alive")
(. wrt println (str "Content-Length: " content-length))
(. wrt print "\r\n")
(. wrt print page-string)
(. wrt flush)
(. wrt close)))

(defn listen-and-respond [ss]
(let [client (. ss accept)]
(start-thread #([client]
                  (let [wrt (new PrintWriter (new BufferedWriter (new OutputStreamWriter (. client (getOutputStream)))))]        
                    (serve-page wrt))))))

(defn create-server [port]
(let [ss (new ServerSocket port)]
(start-thread #(when-not (. ss (isClosed))
                 (try (listen-and-respond ss)
                      (catch SocketException e))
                 (recur)))
ss)) 

(defn -main [& args]
(println "Server is starting")
(let [port (Integer/parseInt (first args))]
(create-server port)))

错误似乎在抱怨这一行:

                (serve-page wrt))))))

但这是一个函数名和一个PrintWriter对象。错误消息表明这是关于带键的地图。这个错误毫无意义。

有什么建议吗?

1 个答案:

答案 0 :(得分:4)

#([client]
   (let [wrt (new PrintWriter (new BufferedWriter (new OutputStreamWriter (. client (getOutputStream)))))]        
     (serve-page wrt)))

是胡说八道。如果您想要一个带有命名参数的lambda,请使用fn表单:

(fn [client]
  (let [wrt (new PrintWriter (new BufferedWriter (new OutputStreamWriter (. client (getOutputStream)))))]        
    (serve-page wrt)))