什么时候创建协议?

时间:2014-03-17 19:09:17

标签: class clojure protocols classloader

我在理解协议如何在Clojure中工作时遇到了问题。更具体地说,我认为我的问题与生成类时的相关(?)。

我设法通过简单的以下案例重现了我的问题。我有三个文件:

core.clj

(ns so.core
  (:require [so.soproto :refer :all])
  (:import  [so.soimpl AImpl])
)

(defn -main [] (println "Hello, World!"))

soproto.clj

(ns so.soproto)

(defprotocol A
  (do-smth [this]))

soimpl.clj

(ns so.soimpl
    (:require [so.soproto :refer :all]))

(deftype AImpl
    []
  A
  (do-smth [this] (println "whatever")))

现在,如果我尝试" lein run",我明白了:

$ lein run
Exception in thread "main" java.lang.ClassNotFoundException: so.soimpl.AImpl

我可以使用以下过程从Emacs重现该问题:

  • 打开 core.clj
  • 致电Emacs' 苹果酒插孔式
  • 将苹果酒的REPL切换到命名空间 so.core
  • 苹果酒-EVAL-缓冲

当然,我得到了同样的例外:

java.lang.ClassNotFoundException: so.soimpl.AImpl

现在我可以修复"这样做可以解决Emacs内部的问题:

  • 切换到缓冲区 soimpl.clj
  • 苹果酒-EVAL-缓冲
  • 切换回 core.clj
  • cider-eval-buffer - >现在事情做得很好

那我怎样才能得到&#34; lein run&#34;上班?我怎么能从cider / Emacs只在 core.clj 上做 cider-eval-buffer 而无需打开/评估包含协议实现的文件?< / p>

1 个答案:

答案 0 :(得分:3)

如果要导入类,则需要先编译它。将:aot [so.soimpl]添加到lein的project.clj中的defproject选项。

但是,请注意,您并不需要AOT编译/导入AImpl来使用它。只需在构造函数中refer

<击> (:import [so.soimpl AImpl])

(require [so.soimpl :refer (->AImpl)])

请参阅最近的answer