代码之家  ›  专栏  ›  技术社区  ›  Rob Lachlan

如何定义实现servlet接口的clojure类型?

  •  7
  • Rob Lachlan  · 技术社区  · 16 年前

    我试图使用deftype(来自最前沿的clojure1.2分支)创建一个实现javaservlet接口的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]
    

    这对我来说没什么意义,因为我要归零。因此,方法的返回类型为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)
    
    1 回复  |  直到 16 年前
        1
  •  20
  •   Chouser    16 年前

    尝试不使用任何类型提示:

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

    the web page about deftype

    • 如果你漏掉了所有的提示:我会试试 接口

      • 这是首选
      • 如果您提供任何提示,则不会进行任何推断,因此所有提示(或 对于参数和返回类型

    来自 (doc deftype) :

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