Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Interface 当可调用函数是Clojure函数时,从ScheduledFutureTask获取nil而不是返回值_Interface_Clojure_Interop_Scheduled Tasks - Fatal编程技术网

Interface 当可调用函数是Clojure函数时,从ScheduledFutureTask获取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

我正在尝试使用Executors.newSingleThreadScheduledExecutor调度Clojure函数。麻烦的是,对结果ScheduledFutureTask调用.get会返回nil而不是函数的结果

我以希基先生对期货的实施为模型

(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*的呼叫。如果这造成了任何混乱,很抱歉。谢谢!为了以后的参考,我必须输入提示所有参数。谢谢!为了将来的参考,我必须输入所有的参数。