首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法使用ns :gen-class中另一个命名空间中的类

无法使用ns :gen-class中另一个命名空间中的类
EN

Stack Overflow用户
提问于 2017-08-27 03:53:00
回答 1查看 714关注 0票数 6

我在sre.plan.dsl.constraint名称空间中有一个名为ConstraintLookupdefrecord。我想在sre.plan.compiler名称空间上的gen-class方法中使用它生成的类:

代码语言:javascript
复制
(ns sre.plan.compiler
  (:require
    [sre.plan.dsl.constraint :as constraint])
  (:import (sre.plan.dsl.constraint ConstraintLookup))
  (:gen-class
    :name sre.plan.Compiler
    :methods [^:static [makeConstraintLookupFromTargetsAndBounds 
                         [Iterable Iterable] ConstraintLookup]]))

我正在使用nebula-clojure插件和Gradle进行编译。编译器在遇到ns声明时会发出错误:

代码语言:javascript
复制
> Task :sre:compileClojure
Exception in thread "main" java.lang.ClassNotFoundException: java.lang.ConstraintLookup, compiling:(sre/plan/compiler.clj:1:1)

类似地,当在方法声明中使用完全限定的sre.plan.dsl.constraint.Constraint时,我得到:

代码语言:javascript
复制
Exception in thread "main" java.lang.ClassNotFoundException: sre.plan.dsl.constraint.ConstraintLookup, compiling:(sre/plan/compiler.clj:1:1)

这里的问题是什么?我迷路了。

更新:

引用的ns如下所示:

代码语言:javascript
复制
(ns sre.plan.dsl.constraint
  (:require [clojure.set :refer :all]
            [clojure.algo.generic.functor :refer :all]))

(defrecord ConstraintLookup [free bound])

更新:

在我看来,在gen-class中,无论如何都必须使用完全限定的类名。然而,我仍然不明白为什么带有完全限定名的版本不起作用。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-08-29 10:00:20

ns宏内的:gen-class指令很可能不会引用作为:require的副作用以相同形式生成的类。由ns宏发出的代码在调用任何require之前调用gen-class。因此,在调用gen-class时,所需的命名空间尚未编译。在从defrecord生成任何类之前,都会调用gen-class

ns的行为可以在in the source code中看到,也可以在使用macroexpand的repl中看到

代码语言:javascript
复制
(clojure.pprint/pprint (macroexpand '(ns sre.plan.compiler
  (:require
    [sre.plan.dsl.constraint :as constraint])
  (:import (sre.plan.dsl.constraint ConstraintLookup))
  (:gen-class
    :name sre.plan.Compiler
    :methods [^:static [makeConstraintLookupFromTargetsAndBounds 
                         [Iterable Iterable] ConstraintLookup]]))))
;; (do
;;  (clojure.core/in-ns 'sre.plan.compiler)
;;  (clojure.core/with-loading-context
;;    (clojure.core/gen-class
;;     :name
;;     "sre.plan.compiler"
;;     :impl-ns
;;     sre.plan.compiler
;;     :main
;;     true
;;     :name
;;     sre.plan.Compiler
;;     :methods
;;     [[makeConstraintLookupFromTargetsAndBounds
;;       [Iterable Iterable]
;;       ConstraintLookup]])
;;    (clojure.core/refer 'clojure.core)
;;    (clojure.core/require '[sre.plan.dsl.constraint :as constraint])
;;    (clojure.core/import '(sre.plan.dsl.constraint ConstraintLookup)))
;;   (if
;;    (.equals 'sre.plan.compiler 'clojure.core)
;;    nil
;;    (do
;;     (clojure.core/dosync
;;      (clojure.core/commute
;;       @#'clojure.core/*loaded-libs*
;;       clojure.core/conj
;;       'sre.plan.compiler))
;;     nil)))

为了解决这个问题,我们可以在ns之后调用gen-class。例如:

代码语言:javascript
复制
(ns sre.plan.compiler
  (:require
    [sre.plan.dsl.constraint :as constraint])
  (:import (sre.plan.dsl.constraint ConstraintLookup)))

(gen-class
 :impl-ns
 sre.plan.compiler
 :main
 true
 :name
 sre.plan.Compiler
 :methods
 [[makeConstraintLookupFromTargetsAndBounds
   [Iterable Iterable]
   sre.plan.dsl.constraint.ConstraintLookup]])
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45899142

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档