Clojure gen-class 可变参数构造函数

8
在构造函数映射和后续的-init定义中,如果超类有多个构造函数且其中一个是varargs,我该如何表示可变参数构造函数?
2个回答

2

由于可变参数本质上是对象数组的语法糖,因此您可以将“[Ljava.lang.Object;”作为构造函数参数的类型。

以下是一些示例代码:

(ns t.vtest
  (:gen-class
   :implements   [clojure.lang.IDeref]
   :init init
   :state state
   :constructors {["[Ljava.lang.Object;"] []}))
   ;;                                      ^-----------------------
   ;; You should put "[Ljava.lang.Object;" for superclass varargs constructor here
   ;; I left it blank for the sake of working example 

(defn -init
  [args]
  (println "first element of args" (aget args 0) "total elements" (alength args))
  [[] (into [] args)])

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

这就是在REPL中的样子

user=> @(t.vtest. (into-array Object ["A" "B" 1 2]))
first element of args A total elements 4
["A" "B" 1 2]

它并没有解决问题陈述中的问题。它生成接受数组的方法,而不是定义一个可变参数方法。这不一样。区别在于,可变参数由生成的字节码中的特殊ACC_VARARGS opscode标记,而Clojure目前不支持它。 - Lambder

1

由于Clojure目前不支持此功能,您需要使用以下内容进行修补:https://groups.google.com/forum/#!topic/clojure/HMpMavh0WxA.

然后使用新的元标记来使用它:

(ns t.vtest 
  (:gen-class 
   :implements   [clojure.lang.IDeref]
   :init init
   :state state
   :constructors {^:varargs ["[Ljava.lang.Object;"] []} 
  ))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接