in the :constructors map and subsequent -init definitions, how do I represent a varargs constructor (assuming the superclass has multiple constructors of which one is varargs) ?
clojure gen-class varargs constructor
Asked Answered
Since varargs are essentially syntax sugar for Object arrays, you could just use "[Ljava.lang.Object;" as the type of constructor's parameter.
Here's some sample code:
(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))
and that's how it looks in REPL
user=> @(t.vtest. (into-array Object ["A" "B" 1 2]))
first element of args A total elements 4
["A" "B" 1 2]
It doesn't solve problem stated in question. Rather than defining a vararg method it generates method accepting array. This is not the same. The difference is that the vararg is flagged by special ACC_VARARGS opscode in generated byte-code which clojure don't support at the moment. –
Karonkaross
Since clojure don't support it at the moment you need to patch it with: https://groups.google.com/forum/#!topic/clojure/HMpMavh0WxA.
And use it with new meta tag:
(ns t.vtest
(:gen-class
:implements [clojure.lang.IDeref]
:init init
:state state
:constructors {^:varargs ["[Ljava.lang.Object;"] []}
))
© 2022 - 2024 — McMap. All rights reserved.