2

我跑了lein new app hm,然后hm/src/hm编辑core.clj为:

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

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

并且hashmap.clj是:

(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)

目标是围绕 HashMap 进行包装,以便我可以理解 Clojure 以及它与 Java 的关系。我对 Clojure 还很陌生。但是,当我编译它时,我在hashmap.clj. 我怎样才能使这项工作?

4

2 回答 2

0

注意:这是对您问题的直接回答。我不建议您以这种方式学习 Clojure。


您需要先编译您的类,然后才能运行它们。在您的 project.clj 中将其添加到地图中:

:aot [hm.hashmap]

然后你需要运行lein compile才能编译这些类。您应该看到输出说明hm.hashmap该类已编译。之后运行lein run以调用hm.core.

我删除了:methods您的 gen-class 的一部分,因为您已经在下面定义了它们,这导致了奇怪的java.lang.,错误。你会遇到其他错误,但这应该足以让你通过这个问题。

于 2013-07-31T16:26:46.780 回答
0

您的代码还有一些其他问题,但这里的直接问题是签名add不完整。你的add回报this,一个hm.hashmap

要修复,请更改签名以返回一个Object,或者,通过额外的编辑,一个java.util.HashMap. 如果您希望它按其他方式工作,您还需要扩展而不是封装。

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

最后更改-maincore.clj调用方法 using.add而不是尝试访问 private -add

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

然后

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

应该打印

#<hashmap {foo=bar}>

hm.hashmap请注意,据我所知,由于符号解析的时间,您不能指定在签名中返回一个。请参阅GC 问题 81:当类返回 self 时编译 gen-class 失败

于 2013-07-31T17:29:46.280 回答