以下作品。结果是“你好世界”
(def ^Callable f (fn [] "hello world"))
(let [e (java.util.concurrent.Executors/newSingleThreadExecutor)]
(try
(.get (.submit e f))
(finally (.shutdown e))))
但以下情况并非如此。 get
的结果是nil
(def e (java.util.concurrent.Executors/newSingleThreadExecutor))
(.get (.submit e f))
为什么呢?我检查了f
是否被调用,用一些有副作用的东西替换它。我能看到的唯一区别是e
在一个let
和另一个def
中绑定。
另一个问题。如果我没有^Callable
的{{1}}类型提示,则第一个示例会安静地返回f
。由于nil
同时为f
和Runnable
,因此不应该为提交调用抛出异常“找到多个匹配方法”吗?如果我使用Callable
定义f
,如下所示,则抛出异常
let
由于
答案 0 :(得分:4)
问题是无法在
中推断出e
的类型
(def e (java.util.concurrent.Executors/newSingleThreadExecutor))
当我将其更改为
时(def ^java.util.concurrent.ExecutorService e (java.util.concurrent.Executors/newSingleThreadExecutor))
然后(.get (.submit e f))
给出正确答案"hello world"
。当使用e
定义let
时,clojure会以某种方式推断出正确的类型,因此不需要类似的类型提示。
将*warn-on-reflection*
设置为true
有助于调试此问题。