2010-05-18 8 views
7

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) 

Antwort

20

Versuchen ohne Typ Hinweise:

(deftype servlet [] 
    javax.servlet.Servlet 
    (service [this request response] 
    ...body...)) 

Von the web page about deftype:

  • , wenn Sie alle Hinweise auslassen: wird versuchen, auf denselben Namen/arity Methode in Schnittstelle (n)

    • diese
    • bevorzugt wird, übereinstimmen, wenn Sie überhaupt keine Hinweise liefern, keine Folgerung erfolgt, so dass alle Hinweise (oder Standard von Object) muss korrekt, für beide Argumente und Rückgabetyp

Und von (doc deftype):

Falls nicht angegeben, werden sie geschlossen werden, so geben Sie sollten Hinweise für Begriffsklärung reserviert werden.

+0

Ah, perfekt. Das beantwortet alles, danke. –