Interface 当可调用函数是Clojure函数时,从ScheduledFutureTask获取nil而不是返回值
我正在尝试使用Executors.newSingleThreadScheduledExecutor调度Clojure函数。麻烦的是,对结果ScheduledFutureTask调用.get会返回nil而不是函数的结果 我以希基先生对期货的实施为模型Interface 当可调用函数是Clojure函数时,从ScheduledFutureTask获取nil而不是返回值,interface,clojure,interop,scheduled-tasks,Interface,Clojure,Interop,Scheduled Tasks,我正在尝试使用Executors.newSingleThreadScheduledExecutor调度Clojure函数。麻烦的是,对结果ScheduledFutureTask调用.get会返回nil而不是函数的结果 我以希基先生对期货的实施为模型 (ns my.ns (:import (java.util.concurrent Executors ThreadFactory TimeUnit))) (def ^:private thread-pool-scheduler (atom
(ns my.ns
(:import (java.util.concurrent Executors ThreadFactory TimeUnit)))
(def ^:private thread-pool-scheduler (atom nil))
(def ^:private thread-pool-counter (agent 0))
(defn- get-and-increment-thread-id []
(-> thread-pool-counter (send inc) deref))
(def ^:private thread-factory
(reify ThreadFactory
(newThread [this f]
(let [thread (Thread. f)]
(.setName thread (format "clojure-scheduled-future-thread-pool-%d"
(get-and-increment-thread-id)))
thread))))
(defn scheduled-future-call [^Callable f ^long delay ^TimeUnit unit]
(.schedule (scheduled-futures-executor) (bound-fn* f) delay unit))
(defn start-scheduled-futures-executor! []
(reset! thread-pool-scheduler
(Executors/newSingleThreadScheduledExecutor thread-factory)))
(defn scheduled-futures-executor []
(or @thread-pool-scheduler
(start-scheduled-futures-executor!)))
一切正常,适当时会产生副作用,例如,计划打印正常。
但是,调用生成的ScheduledFutureTask的get方法总是得到nil
e、 g.日程安排+5
我尝试显式扩展Callable,尝试忽略绑定fn*,但结果相同:
(defprotocol ISchedule
(schedule [this delay time-unit]))
(extend Callable
ISchedule
{:schedule (fn [this delay time-unit]
(.schedule (scheduled-futures-executor) this delay time-unit))})
我的直觉是ScheduledExecutorService选择scheduleRunnable,long,TimeUnit而不是scheduleCallable,long,TimeUnit,但是类型提示不应该解决这个问题吗
非常感谢您的帮助和提示
我的直觉是ScheduledExecutorService选择scheduleRunnable,long,TimeUnit而不是scheduleCallable,long,TimeUnit
我想你是对的,只是我把Callable具体化了,而且工作正常。我还将Callable添加到import语句中的类列表中
编辑:我还删除了对绑定fn的调用*
请查看:
(defn make-callable [f] (reify Callable (call [this] (f))))
(def cat (make-callable (fn [] (println "meeow") "i am a cat")))
(def who-are-you? (scheduled-future-call cat 2 TimeUnit/SECONDS))
(println "Tell me who you are!\n\t" (.get who-are-you?))
产出:
meeow
Tell me who you are!
i am a cat
我的直觉是ScheduledExecutorService选择scheduleRunnable,long,TimeUnit而不是scheduleCallable,long,TimeUnit
我想你是对的,只是我把Callable具体化了,而且工作正常。我还将Callable添加到import语句中的类列表中
编辑:我还删除了对绑定fn的调用*
请查看:
(defn make-callable [f] (reify Callable (call [this] (f))))
(def cat (make-callable (fn [] (println "meeow") "i am a cat")))
(def who-are-you? (scheduled-future-call cat 2 TimeUnit/SECONDS))
(println "Tell me who you are!\n\t" (.get who-are-you?))
产出:
meeow
Tell me who you are!
i am a cat
f上的^Callable提示对您没有好处,因为您只是调用绑定的fn,其结果不是type hinted。你需要暗示你实际传递给的东西。时间表。更重要的是,您需要将目标对象本身提示为执行者,因为如果没有提示目标对象,编译器将相当合理地忽略任何关于参数的提示:如果它不知道目标的类型,它无论如何都必须进行反射
因此,在let-binding1中提示这两件事,您应该会很好。为了消除歧义,您可能需要提示所有其他的论点,但我不这么认为
1注意:不要提示生成它们的表达式,例如^Callable bound fn f。在解释起来很复杂的场景中,这通常有效,但有时无效。最好避免这种情况。f上的^Callable提示对您没有好处,因为您只是调用绑定的fn,其结果不是type hinted。你需要暗示你实际传递给的东西。时间表。更重要的是,您需要将目标对象本身提示为执行者,因为如果没有提示目标对象,编译器将相当合理地忽略任何关于参数的提示:如果它不知道目标的类型,它无论如何都必须进行反射
因此,在let-binding1中提示这两件事,您应该会很好。为了消除歧义,您可能需要提示所有其他的论点,但我不这么认为
1注意:不要提示生成它们的表达式,例如^Callable bound fn f。在解释起来很复杂的场景中,这通常有效,但有时无效。最好避免这种情况。可惜我不能在两篇帖子上打勾作为答案。这一点和阿马洛伊的回答对我帮助很大。很高兴这有帮助。我忘了提到我也取消了对bound fn*的呼叫。很抱歉,如果这造成了任何混乱。很遗憾,我不能勾选两个帖子作为答案。这一点和阿马洛伊的回答对我帮助很大。很高兴这有帮助。我忘了提到我也取消了对bound fn*的呼叫。如果这造成了任何混乱,很抱歉。谢谢!为了以后的参考,我必须输入提示所有参数。谢谢!为了将来的参考,我必须输入所有的参数。