3

似乎 lein 在如何重新编译代码方面是不可预测的。我在一个目录中有一个 gen-class 文件,试图在另一个目录中访问它。例如,给定这个 gen-class:

(ns a.Target
    (:gen-class
     :state state
     :init  init
     :constructors {[String String] []}))

(defn -init
  [m1  m2]
  [[]  (atom {"A" m1 "B" m2})])

(defn -deref
  [this]
  @(.state this))

并尝试从另一个命名空间访问它,减少为尝试 1、2、3 的随机变化:

(ns b.runner
    (:require [a.Target  ] :as Target) ;1
    (:import '(a Target))              ;2
)

(compile 'a.Target) ;3

似乎没有语法可以识别“Target”而不是“a.Target”,所以我在处理 gen-class 的方式上显然有些不正确。这是一个问题,因为我正在尝试使用带注释的提供程序方法访问我们的 guice-injector,并且注释语法似乎不接受完整或简单的类规范:

(definterface TargetProvider (^a.Target getTarget [this] ))
=> Exception in thread "main" java.lang.UnsupportedOperationException: nth not supported on this type:

或简化的:

(definterface TargetProvider (^Target getTarget [this] ))
=> Can't find class java.lang.Target
4

1 回答 1

3

ns 表达式应该(ns b (:import a.Target))不需要:require用于要导入的类。由于ns是宏,所有的符号:require:use和其他选项都不会被评估,所以没有必要引用它们。使用以下ns声明,您的definterface表达式应该可以工作。

(ns b
  (:import a.Target))

(definterface TargetProvider [^a.Target getTarget []])

(->> b.TargetProvider .getMethods seq)
;= (#<Method public abstract a.Target b.TargetProvider.getTarget()>)

编辑

这是使用上面定义的接口的代理代码TargetProvider,我认为这是您在评论中要求的。

请注意,我还修改了接口getTarget方法的声明,删除了this参数,因为它实际上并没有接收到当前实例的引用。使用时proxy有一个隐式绑定的this本地(有关更多信息,请参见此处)。

(let [x (proxy [TargetProvider] []
          (getTarget [] (Target. "x" "y")))]
  (.getTarget x))
于 2014-01-27T20:03:04.327 回答