2024 年 Clojure 状态调查!中分享您的想法。

欢迎!有关如何工作的更多信息,请参阅关于页面。

+1

使用 clojure 1.10.3

user> (def p (promise))
#'user/p
user> (def wrapper
        (reify
          clojure.lang.IDeref
          (deref [_] @p)))
#'user/wrapper
user> wrapper ;; => repl hangs here

在上面的会话中,REPL阻塞在最后一个语句上。我不明白为什么会有这种情况。我预计 @wrapper 会阻塞,评估 wrapper,但我预计它会返回某种类型的对象。我漏掉了什么吗?

1 答案

+2
 
最佳答案

您的REPL试图以一种有意义的方式来打印 wrapper,这包括在对其进行 deref 后获取的值。

(defn- deref-as-map [^clojure.lang.IDeref o]
  (let [pending (and (instance? clojure.lang.IPending o)
                     (not (.isRealized ^clojure.lang.IPending o)))
        [ex val]
        (when-not pending
          (try [false (deref o)]
               (catch Throwable e
                 [true e])))]
    {:status
     (cond
      (or ex
          (and (instance? clojure.lang.Agent o)
               (agent-error o)))
      :failed

      pending
      :pending

      :else
      :ready)

     :val val}))

(defmethod print-method clojure.lang.IDeref [o ^Writer w]
  (print-tagged-object o (deref-as-map o) w))

请注意,打印出 promise 正常工作,因为上面的第一个函数明确检查了它的值。

...