简体   繁体   中英

How do I set up classes in a Lein project?

I ran lein new app hm , then in hm/src/hm edited core.clj to be:

(ns hm.core
  (:gen-class)
  (:use [hm.hashmap]))

(defn -main []
  (def j (new hm.hashmap))
  (-add j "foo" "bar")
  (println j))

and hashmap.clj to be:

(ns hm.hashmap
  (:gen-class
   :methods [[hashmap [] java.util.HashMap]
             [add [String String]]]))

(defn -hashmap []
  (def h (new java.util.HashMap))
  h)

(defn -add [this key value]
  (. this put key value)
  this)

The goal is to make a wrapper around the HashMap so I can understand Clojure and how it ties with Java. I'm fairly new to Clojure. However, when I compile this, I get a lot of ClassNotFoundException in hashmap.clj . How can I make this work?

Note: This is a direct answer to your question. I don't recommend that you learn Clojure this way.


You need to compile your classes before you can run them. In your project.clj add this to the map:

:aot [hm.hashmap]

Then you need to run lein compile in order to compile the classes. You should see output saying the hm.hashmap class was compiled. After that run lein run to invoke the "main "function in hm.core .

I removed the :methods part of your gen-class because you're already defining them below, and that was causing the weird java.lang., error. You're going to run into other errors, but this should be enough to get you passed this issue.

Your code has some other issues, but the immediate problem here is that the signature of add is incomplete. Your add returns this , a hm.hashmap .

To fix, change the signature to return an Object , or, with additional edit, a java.util.HashMap . If you want this to work as otherwise written, you'll also need to extend rather than encapsulate.

(ns hm.hashmap
  (:gen-class
   :extends java.util.HashMap
   :methods [[add [String String] java.util.HashMap]]))

Finally change -main in core.clj to call the method using .add instead of trying to access the private -add .

...
(.add j "foo" "bar")
...

Then

lein clean
lein compile hm.core hm.hashmap
lein run

should print

#<hashmap {foo=bar}>

Note that you cannot, as far as I know, specify returning an hm.hashmap in the signature due to the timing of the symbol resolution. See GC Issue 81: compile gen-class fail when class returns self .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM