【问题标题】:How can I define a clojure type that implements the servlet interface?如何定义实现 servlet 接口的 clojure 类型?
【发布时间】:2011-02-20 16:40:17
【问题描述】:

我正在尝试使用 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]

这对我来说没有意义,因为我返回 nil。因此,该方法的返回类型为 void 的事实应该不是问题。例如,对于 java.util.Set 接口:

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

编译没有问题。

那么我在 Servlet 接口上做错了什么?

要明确: 我知道典型的情况是子类化servlet抽象类之一,而不是直接实现这个接口,但它仍然应该可以做到这一点。

堆栈跟踪:

(deftype servlet... 的堆栈跟踪是:

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)

【问题讨论】:

    标签: servlets clojure java-interop deftype


    【解决方案1】:

    尝试不带任何类型提示:

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

    来自the web page about deftype

    • 如果您忽略所有提示:将尝试 匹配相同的名称/数量方法 接口

      • 这是首选
      • 如果您提供任何提示,则不会进行任何推断,因此所有提示(或 对象的默认值)必须正确, 对于参数和返回类型

    来自(doc deftype)

    如果未提供,它们将被推断,因此应保留类型提示以消除歧义。

    【讨论】:

      猜你喜欢
      • 2019-07-19
      • 1970-01-01
      • 2011-09-07
      • 2018-09-06
      • 2015-01-18
      • 1970-01-01
      • 1970-01-01
      • 2023-03-03
      • 1970-01-01
      相关资源
      最近更新 更多