Ich versuche, deftype (aus dem Clojure 1.2 Branch) zu verwenden, um eine Java-Klasse zu erstellen, die die Java-Servlet-Schnittstelle implementiert. Ich würde erwarten, dass der folgende Code kompiliert wird (obwohl es nicht sehr nützlich ist).Wie kann ich einen Clojure-Typ definieren, der die Servlet-Schnittstelle implementiert?
(ns foo [:import [javax.servlet Servlet ServletRequest ServletResponse]])
(deftype servlet []
javax.servlet.Servlet
(service [this
#^javax.servlet.ServletRequest request
#^javax.servlet.ServletResponse response]
nil))
Aber es kompiliert nicht. Der Compiler erzeugt folgende Meldung:
Was für mich keinen Sinn ergibt, weil ich null zurückgebe. Daher sollte die Tatsache, dass der Rückgabetyp der Methode ungültig ist, kein Problem darstellen. Zum Beispiel für die Schnittstelle java.util.Set:
(deftype bar [#^Number n] java.util.Set (clear [this] nil))
kompiliert ohne Problem.
Also, was mache ich falsch mit der Servlet-Schnittstelle?
Um klar zu sein: Ich weiß, dass der typische Fall ist, eine der abstrakten Servlet Klassen zu untergliedern, anstatt diese Schnittstelle direkt zu implementieren, aber es sollte immer noch möglich sein, dies zu tun.
Stack Trace:
Der Stack-Trace für die (Deftype Servlet ... ist:
Mismatched return type: service, expected: void, had: java.lang.Object
[Thrown class java.lang.IllegalArgumentException]
Restarts:
0: [ABORT] Return to SLIME's top level.
Backtrace:
0: clojure.lang.Compiler$NewInstanceMethod.parse(Compiler.java:6461)
1: clojure.lang.Compiler$NewInstanceExpr.build(Compiler.java:6119)
2: clojure.lang.Compiler$NewInstanceExpr$DeftypeParser.parse(Compiler.java:6003)
3: clojure.lang.Compiler.analyzeSeq(Compiler.java:5289)
4: clojure.lang.Compiler.analyze(Compiler.java:5110)
5: clojure.lang.Compiler.analyze(Compiler.java:5071)
6: clojure.lang.Compiler.eval(Compiler.java:5347)
7: clojure.lang.Compiler.eval(Compiler.java:5334)
8: clojure.lang.Compiler.eval(Compiler.java:5311)
9: clojure.core$eval__4350.invoke(core.clj:2364)
10: swank.commands.basic$eval_region__673.invoke(basic.clj:40)
11: swank.commands.basic$eval_region__673.invoke(basic.clj:31)
12: swank.commands.basic$eval__686$listener_eval__687.invoke(basic.clj:54)
13: clojure.lang.Var.invoke(Var.java:365)
14: foo$eval__2285.invoke(NO_SOURCE_FILE)
15: clojure.lang.Compiler.eval(Compiler.java:5343)
16: clojure.lang.Compiler.eval(Compiler.java:5311)
17: clojure.core$eval__4350.invoke(core.clj:2364)
18: swank.core$eval_in_emacs_package__320.invoke(core.clj:59)
19: swank.core$eval_for_emacs__383.invoke(core.clj:128)
20: clojure.lang.Var.invoke(Var.java:373)
21: clojure.lang.AFn.applyToHelper(AFn.java:169)
22: clojure.lang.Var.applyTo(Var.java:482)
23: clojure.core$apply__3776.invoke(core.clj:535)
24: swank.core$eval_from_control__322.invoke(core.clj:66)
25: swank.core$eval_loop__324.invoke(core.clj:71)
26: swank.core$spawn_repl_thread__434$fn__464$fn__465.invoke(core.clj:183)
27: clojure.lang.AFn.applyToHelper(AFn.java:159)
28: clojure.lang.AFn.applyTo(AFn.java:151)
29: clojure.core$apply__3776.invoke(core.clj:535)
30: swank.core$spawn_repl_thread__434$fn__464.doInvoke(core.clj:180)
31: clojure.lang.RestFn.invoke(RestFn.java:398)
32: clojure.lang.AFn.run(AFn.java:24)
33: java.lang.Thread.run(Thread.java:637)
Ah, perfekt. Das beantwortet alles, danke. –