Как вы используете тип за пределами своего собственного пространства имен в clojure? - PullRequest
12 голосов
/ 11 сентября 2010

У меня есть проект с leiningen, который называется techne. Я создал модуль 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)

Если я удаляю test-scrub, все работает нормально. Почему: использовать techne.scrub «импортировать» определения функций, но не определения типов? Как мне сослаться на определения типов?

Ответы [ 2 ]

16 голосов
/ 11 сентября 2010

Поскольку deftype генерирует класс, вам, вероятно, потребуется импортировать этот класс Java в techne.scrub-test с помощью (: import [techne.scrub Scrub]) в определении ns.

Я на самом деле написал то же самое в отношении отсылки здесь:

Еще одна вещь, которую вы можете сделать, это определить функцию конструктора в scrub:

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

и тогда вам не нужно будет импортировать Scrub в test-scrub.

1 голос
/ 30 декабря 2014

Я добавляю импорт, но получаю ту же проблему. Я тестирую с пакетом Expectations 2.0.9, пытаюсь импортировать узел типа и тип 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:

*************** 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

Однако предложение использовать фабричный метод является жизнеспособным обходным путем.

...