go
当我偶然发现一个奇怪的编译错误时,我正在实现一个涉及 core.async 块的函数:
CompilerException java.lang.IllegalArgumentException:
No method in multimethod '-item-to-ssa' for dispatch value: :protocol-invoke,
compiling:(NO_SOURCE_PATH:2:3)
我做了一些实验来尝试解决这个问题,发现它非常通用。假设我有任何协议MyProtocol
:
(defprotocol MyProtocol
(do-something [this param] "some method"))
以下代码将无法编译,除了我在上面向您展示的异常之外:
(defn uncompilable! [me ch]
(go
(do-something me (<! ch)) ;; apparently, it hurts to use <! in a protocol method invocation
))
但是,以下 2 将编译没有任何问题:
(defn compilable! [me ch]
(let [call-it #(do-something me %)] ; wrapping the protocol call in a function
(go
(call-it (<! ch))
)))
(defn compilable-2! [me ch]
(go
(let [my-value (<! ch)] ; taking out the <! call
(do-something me my-value))
))
显然,这与在clojure.core.async.impl.ioc-macros-item-to-ssa
命名空间中可以找到的多方法有关 。
在我看来,“<!
内部协议方法调用表单”是go
宏无法处理的情况。
有人对此有解释吗?我应该提交错误吗?
这发生使用[org.clojure/core.async "0.1.346.0-17112a-alpha"]
and both [org.clojure/clojure "1.7.0-alpha1"]
and [org.clojure/clojure "1.6.0"]
。
仅供参考,这发生在我实现一个 Ring 类型的中间件以结合 http-kit 异步 Web 服务器和 core.async 时。