如何在clojure中使用自己的命名空间之外的类型?

时间:2010-09-11 11:22:50

标签: testing clojure leiningen deftype

我与leiningen建立了一个名为techne的项目。我创建了一个名为scrub的模块,其中包含一个名为Scrub的类型和一个名为foo的函数。

技艺/ scrub.clj:

(ns techne.scrub)
  (deftype Scrub [state]
    Object
     (toString [this]
     (str "SCRUB: " state)))

(defn foo
  [item]
  (Scrub. "foo")
  "bar")

技艺/ 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)

如果我删除test-scrub,一切正常。为什么:使用techne.scrub'import'函数定义而不是类型定义?如何引用类型定义?

2 个答案:

答案 0 :(得分:16)

因为deftype生成了一个类,您可能需要在ns定义中使用(:import [techne.scrub Scrub])在techne.scrub-test中导入该Java类。

我实际上在这里写了关于defrecord的同样的事情:

您可以做的另一件事是在scrub中定义构造函数:

(defn new-scrub [state] 
  (Scrub. state))

然后你不需要在test-scrub中导入Scrub。

答案 1 :(得分:0)

我添加了导入,但是遇到了同样的问题。我正在使用Expectations包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

然而,建议使用工厂方法是一种可行的解决方法。