Подтвердить что ты не робот

Как вы используете тип за пределами своего собственного пространства имен в clojure?

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

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

4b9b3361

Ответ 1

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

На самом деле я написал то же самое в отношении defrecord:

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

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

и вам не нужно будет импортировать Scrub в тестовый скраб.

Ответ 2

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

и вывод от leaine 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

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