2012-04-04 3 views
5

два файлаConfused о решении ClassName

types.clj:

(ns test.types) 

(defrecord Price [date price]) 
(defrecord ProductPrice [name prices]) 

core.clj (это нормально)

(ns test.core 
    (:use [test.types]) 
    (:use [clojure.string :only (split)])) 


(defn read-data [file] 
    (let [name (subs (.getName file) 0 4)] 
    (with-open [rdr (clojure.java.io/reader file)] 
     (doall (map #(apply ->Price (split % #"\t")) (drop 2 (line-seq rdr))))))) 

core.clj (java.lang.IllegalArgumentException: Невозможно для разрешения имени класса: ProductPrice)

(ns test.core 
    (:use [test.types]) 
    (:use [clojure.string :only (split)])) 


(defn read-data [file] 
    (let [name (subs (.getName file) 0 4)] 
    (with-open [rdr (clojure.java.io/reader file)] 
     (ProductPrice. name (doall (map #(apply ->Price (split % #"\t")) (drop 2 (line-seq rdr)))))))) 

core.clj (это нормально)

(ns test.core 
    (:use [test.types]) 
    (:use [clojure.string :only (split)])) 

(defrecord tProductPrice [name prices]) 
(defn read-data [file] 
    (let [name (subs (.getName file) 0 4)] 
    (with-open [rdr (clojure.java.io/reader file)] 
     (tProductPrice. name (doall (map #(apply ->Price (split % #"\t")) (drop 2 (line-seq rdr))))))) 

core.clj (java.lang.IllegalStateException: -> ProductPrice уже относится к: # 'test.types/-> ProductPrice в пространстве имен: test.core)

(ns test.core 
    (:use [test.types]) 
    (:use [clojure.string :only (split)])) 

(defrecord ProductPrice [name prices]) 
(defn read-data [file] 
    (let [name (subs (.getName file) 0 4)] 
    (with-open [rdr (clojure.java.io/reader file)] 
     (ProductPrice. name (doall (map #(apply ->Price (split % #"\t")) (drop 2 (line-seq rdr))))))) 

Я полностью смущен об этих исключениях. И я не могу больше использовать «запись», кроме некоторых простых примеров из clojure.org и книг.

Любая помощь, спасибо!

ответ

9

defrecord создает класс java в пакете, названном именем текущего пространства имен. (ProductPrice. ...) является вызовом конструктора этого типа; это java interop - не обычный вызов функции.

Вы не можете ссылаться на класс, определенный вне java.lang или текущего пространства имен, если вы явно не указали импорт или укажите полное название пакета. Это включает вызов его конструктора.

Итак, чтобы устранить проблему, вам необходимо импортировать Price и ProductPrice.

(ns test.core (:import [test.types Price])) 
(Price. ...) 

или вызвать полный класс + пакет имя:

(test.types.Price. ...) 
+2

Обратите внимание, что дефис/подчеркивания коверкая в именах пространства имен вызывает путаницу здесь. Если вы 'defrecord'' что-то в пространстве имен' 'clj-test'', он создаст класс в пакете' 'clj_test'', и ваш' ': import'' должен будет отразить это – sw1nn

+0

@Joost Diepenmaat Спасибо! Почему '-> Цена' может использоваться без импорта? И «import», похоже, не работает для меня, все еще «java.lang.RuntimeException: java.lang.ClassNotFoundException: test.types.ProductPrice» – Kane

+0

-> Цена - это дополнительно созданная вспомогательная функция, которая является реальной функцией clojure и поэтому экспортируется когда вы «используете» пакет. Кроме того, вы должны убедиться, что типы записей скомпилированы ('use' или' require' пространство имен, в котором они определены), прежде чем вы сможете «импортировать» их. Если вы не можете заставить это работать, создайте новый вопрос с примером кода. –