您如何在Clojure中使用其自己的名称空间之外的类型?
题
我有一个名为Techne的Leiningen的项目。我创建了一个名为Scrub的模块,其中具有称为scrub的类型和一个称为foo的函数。
techne/scrub.clj:
(ns techne.scrub)
(deftype Scrub [state]
Object
(toString [this]
(str "SCRUB: " state)))
(defn foo
[item]
(Scrub. "foo")
"bar")
techne/scrub_test.clj:
(ns techne.scrub-test
(:use [techne.scrub] :reload-all)
(:use [clojure.test]))
(deftest test-foo
(is (= "bar" (foo "foo"))))
(deftest test-scrub
(is (= (Scrub. :a) (Scrub. :a))))
当我运行测试时,我会发现错误:
Exception in thread "main" java.lang.IllegalArgumentException: Unable to resolve classname: Scrub (scrub_test.clj:11)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:5376)
at clojure.lang.Compiler.analyze(Compiler.java:5190)
at clojure.lang.Compiler.analyzeSeq(Compiler.java:5357)
如果我删除测试库,则一切正常。为什么:使用techne.scrub“导入”函数定义,而不是类型定义?如何引用类型定义?
解决方案
因为 deftype 生成一个类,您可能需要在NS定义中以(:import [techne.scrub scrub])在Techne.scrub-Test中导入Java类。
实际上,我在此处写了同样的事情:
您可以做的另一件事是在scrub中定义构造函数:
(defn new-scrub [state]
(Scrub. state))
然后,您无需在测试中导入磨砂膏。
其他提示
我添加了导入,但会遇到同样的问题。我正在使用“期望软件包2.0.9”测试,试图导入Deftype节点和接口Inode。
在core.clj中:
(ns linked-list.core)
(definterface INode
(getCar [])
(getCdr [])
(setCar [x])
(setCdr [x]))
(deftype Node [^:volatile-mutable car ^:volatile-mutable cdr]
INode
(getCar[_] car)
(getCdr[_] cdr)
(setCar[_ x] (set! car x) _)
(setCdr[_ x] (set! cdr x) _))
在core_test.clj中:
(ns linked-list.core-test
(:require [expectations :refer :all]
[linked-list.core :refer :all])
(:import [linked-list.core INode]
[linked-list.core Node]))
以及Lein Autoexpect的输出:
*************** Running tests ***************
Error refreshing environment: java.lang.ClassNotFoundException: linked-list.core.INode, compiling:(linked_list/core_test.clj:1:1)
Tests completed at 07:29:36.252
但是,使用工厂方法的建议是可行的工作。
不隶属于 StackOverflow