我创建了一个这样的记录:
(defrecord User [user-id email])
:但是当我尝试从另一个名称空间访问它时,我收到错误:
(User. "name" "email")
java.lang.IllegalArgumentException:无法解析类名:用户
我可以这样做:
(oe.model.modelcore.User. "name" "email")
:我知道我需要导入Java类,但是当我这样做时,clojure有没有办法自动执行此操作:
(use 'oe.model.modelcore :reload)
答案 0 :(得分:13)
从技术上讲,您必须要求它(不一定需要使用它),以便编译包含记录定义的文件并创建类。然后,您必须导入它,以便可以构造为Java类。如果你在第一个ns中创建一个构造函数,比如
(defn new-user [id email]
(User. id email))
然后你不需要在调用ns中导入它。
我在这里写了一段时间:
答案 1 :(得分:11)
如果你的名字空间中有-
(破折号),那可能会非常棘手。
事实证明有两个错误:
- 从另一个命名空间导入defrecord不仅仅是:使用。我必须先:要求命名空间,然后导入defrecord。这是一个需要解决的微不足道的问题,我很快就明白了。只有这个在我的情况下不起作用
- 由于我们将Lisp与Java混合,所以Dashes“ - ”和Underscores“_”是一个麻烦。虽然文件系统使用下划线,但Clojure会将内容转换为破折号。辉煌。
所以要修复第二个错误,我使用ns块中的跟随
(ns adder.core (:require building-blocks.activity) (:import [building_blocks.activity Activity]))
https://cyrax.wordpress.com/2013/07/22/clojure-importrequireuse-defrecord-from-another-namespace/
答案 2 :(得分:10)
您必须导入如下记录:
(ns some-ns
(:import [oe.model.modelcore User]))
答案 3 :(得分:10)
在你的问题中,你正在创建一个记录,然后调用作为副作用生成的类的构造函数。为此,您需要导入另一个答案中提到的那个类。
然而,imho首选路径(因为Clojure 1.4)是使用由defrecord生成的构造函数(这里它们将被命名为->User
和map->User
)。这些函数允许您避免互操作形式,只需在构造函数中引用,就像任何其他函数一样。通过避免互操作,这是一个更便携,更少宿主的解决方案:
(ns some-ns
(:require [oe.model.modelcore :refer (->User)]))
(def user (->User "name" "email"))