gpt4 book ai didi

java - 如何在 Clojure 中正确导入用户定义的类

转载 作者:行者123 更新时间:2023-11-30 04:20:46 26 4
gpt4 key购买 nike

我正在使用 Leiningen 和 Clojure,但我一直无法理解为什么 Clojure 使得正确导入 namespace 变得如此困难。这是以下错误

这是我的 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.")))

最佳答案

将您的代码粘贴到新的 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 时,您的 namespace 出现了问题,现在由于 REPL 中的某些 namespace 加载状态而无法加载。您可能想尝试(require :reload 'animals.core),如果这不起作用,请重新启动 REPL。 (如果您再次遇到它,您也可以将整个 REPL 交互粘贴到 ClassNotFoundException 的某个位置。)

另外,关于您的 ns 表单:

  1. 您不应该同时使用 :require:use 相同的命名空间; :use 已经 :require 了。

  2. 更常见的是使用单个 :import 子句(事实上,每个子句类型一个子句);例如,

    (:import (animals.animal Dog Human Arthropod Insect))

    这纯粹是 Clojure 中的风格问题,但在 ClojureScript 中,它实际上是语言所需要的。

关于java - 如何在 Clojure 中正确导入用户定义的类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17129139/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com