我正在使用Leiningen和Clojure,对于我的生活,我无法理解为什么Clojure只是正确导入名称空间这么困难。这是以下错误
这就是我在core.clj
文件中的内容:
; namespace macro
(ns animals.core
(:require animals.animal)
(:use animals.animal)
(:import (animals.animal Dog))
(:import (animals.animal Human))
(:import (animals.animal Arthropod))
(:import (animals.animal Insect)))
; make-animals will create a vector of animal objects
(defn make-animals []
(conj []
(Dog. "Terrier" "Canis lupis familiaris")
(Human. "Human" "Homo sapiens")
(Arthropod. "Brown Recluse" "Loxosceles reclusa")
(Insect. "Fire Ant" "Solenopsis conjurata")))
; print-animals will print all the animal objects
(defn print-animals [animals]
(doseq [animal animals]
(println animal)))
; move-animals will call the move action on each animal
(defn move-animals [animals]
(doseq [animal animals]
(animals.animal/move animal)))
; entry to main program
(defn -main [& args]
(let [animals make-animals]
(do
(println "Welcome to Animals!")
(println "-------------------")
(print-animals animals))))
然后,在REPL,我输入以下内容(在lein
项目的src /目录中):
user> (require 'animals.core)
nil
user> (animals.core/-main)
ClassNotFoundException animals.core java.net.URLClassLoader$1.run (URLClassLoader.java:202)
好的......什么?为什么呢?
作为参考,这里的文件animal.clj
也在animals
目录中:
(ns animals.animal)
(defprotocol Animal
"A simple protocol for animal behaviors."
(move [this] "Method to move."))
(defrecord Dog [name species]
Animal
(move [this] (str "The " (:name this) " walks on all fours.")))
(defrecord Human [name species]
Animal
(move [this] (str "The " (:name this) " walks on two legs.")))
(defrecord Arthropod [name species]
Animal
(move [this] (str "The " (:name this) " walks on eight legs.")))
(defrecord Insect [name species]
Animal
(move [this] (str "The " (:name this) " walks on six legs.")))
答案 0 :(得分:2)
将代码粘贴到一个新的Leiningen项目中,由于-main
中的拼写错误,我收到了不同的错误:(let [animals make-animals] ...)
应为(let [animals (make-animals)] ...)
。通过这一改变,一切正常:
user=> (require 'animals.core)
nil
user=> (animals.core/-main)
Welcome to Animals!
-------------------
#animals.animal.Dog{:name Terrier, :species Canis lupis familiaris}
#animals.animal.Human{:name Human, :species Homo sapiens}
#animals.animal.Arthropod{:name Brown Recluse, :species Loxosceles reclusa}
#animals.animal.Insect{:name Fire Ant, :species Solenopsis conjurata}
nil
顺便说一句,只要在项目目录中的某个位置调用lein repl
,就在哪里无关紧要。
我猜想当你第一次尝试使用require
时你的命名空间有问题,现在由于你的REPL中有一些命名空间加载状态而无法加载它。您可能想尝试(require :reload 'animals.core)
,如果这不起作用,请重新启动REPL。 (如果你再次遇到它,你也可以将你的整个REPL交互粘贴到某个地方的ClassNotFoundException
。)
另外,关于您的ns
表单:
您不应该:require
和:use
同名的名称空间; :use
已经:require
了。
使用单个:import
子句更常见(事实上,每个子句类型只有一个子句);例如,
(:import (animals.animal Dog Human Arthropod Insect))
纯粹是Clojure中的风格问题,但在ClojureScript中,它实际上是语言所必需的。