1

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

这段代码很简单,我很困惑它怎么会出错。我有:

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

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

我编译它,然后 uberjar 它,然后在命令行上启动它。这些行:

(println "Server is starting")

(println "port: " port)

打印出来:

服务器正在启动端口:3457

在下一行,create-server 被调用,我得到这个错误:

Exception in thread "Thread-1" clojure.lang.ArityException: Wrong number of args (0) passed to:     core$create-server$fn
    at clojure.lang.AFn.throwArity(AFn.java:437)
    at clojure.lang.AFn.invoke(AFn.java:35)
    at clojure.lang.AFn.run(AFn.java:24)
    at java.lang.Thread.run(Thread.java:680)

显然,-main 中的行不会有问题,因为我知道“端口”在第一次调用 create-server 之前的行的值为 3457。我还注意到这个错误在 Thread-1 中,所以我认为这段代码以某种我不理解的方式重复出现。

有什么想法吗?

4

1 回答 1

3

如果start-thread最终调用,new Thread(Runnable)那么错误实际上是因为public void run()没有Runnable任何参数。

因为ss是在封闭let表达式中声明的,所以它对您传递给的匿名函数是可见的start-thread

编辑使用 Java 互操作在 REPL 重现您的确切问题(*1在 REPL 中表示“从先前评估返回的值):

user=> (doto (new Thread (fn run [s] (println "blah"))))
#<Thread Thread[Thread-14,5,main]>
user=> (.start *1)
Exception in thread "Thread-14" nil
clojure.lang.ArityException: Wrong number of args (0) passed to: user$eval318$run
at clojure.lang.AFn.throwArity(AFn.java:437)
at clojure.lang.AFn.invoke(AFn.java:35)
at clojure.lang.AFn.run(AFn.java:24)
at java.lang.Thread.run(Thread.java:679)


user=> (doto (new Thread (fn run [] (println "blah"))))
#<Thread Thread[Thread-15,5,main]>
user=> (.start *1)
nilblah
于 2012-09-03T00:03:46.680 回答