Как я могу определить тип clojure, который реализует интерфейс сервлета?

Я пытаюсь использовать deftype (от новейшего ответвления clojure 1.2) для создания класса Java, который реализует интерфейс Servlet Java. Я ожидал бы, что код ниже скомпилирует (даже при том, что это не очень полезно).

(ns foo [:import [javax.servlet Servlet ServletRequest ServletResponse]])

(deftype servlet [] 
   javax.servlet.Servlet 
   (service [this 
         #^javax.servlet.ServletRequest request
         #^javax.servlet.ServletResponse response]
   nil))

Но это не компилирует. Компилятор создает сообщение:

Mismatched return type: service, expected: void, had: java.lang.Object
  [Thrown class java.lang.IllegalArgumentException]

Который не имеет смысла мне, потому что я возвращаю ноль. Таким образом, то, что тип возврата метода является пустым, не должно быть проблемой. Например, для java.util. Интерфейс Set:

(deftype bar [#^Number n] java.util.Set (clear [this] nil))

компиляции без проблемы.

Таким образом, что я делаю неправильно с интерфейсом Servlet?

Быть ясным: Я знаю, что типичный случай должен разделить один на подклассы из абстрактных классов сервлета, а не реализовать этот интерфейс непосредственно, но должно все еще быть возможно сделать это.

Отслеживание стека:

Отслеживание стека для (deftype сервлет...:

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)
7
задан BalusC 18 May 2010 в 12:33
поделиться

1 ответ

Попробуйте без подсказок типа:

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

Из веб-страницы о deftype:

  • если не использовать все подсказки: будет пытаться сопоставить с одноименным методом в интерфейсе(ах)

    • это предпочтительнее
    • если вы предоставите любые подсказки вообще, не будет сделано никакого вывода, поэтому все подсказки (или по умолчанию Object) должны быть корректными, как для аргументов, так и для возвращаемого типа

И из (doc deftype):

Если они не предоставлены, они будут выведены, поэтому подсказки типа должны быть зарезервированы для дизамбигуации.

20
ответ дан 6 December 2019 в 09:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: