使用Clojure的静态方法

时间:2018-12-11 20:33:02

标签: java clojure

我正在尝试在Clojure中实现以下功能:

处理程序:

// http/handlers/EchoHandler.java
package http.handlers;

import org.rapidoid.http.Req;
import org.rapidoid.u.U;

import java.util.Map;

public class EchoHandler {

    public static Map<String, String> handleEcho(Req req) {
        return U.map(req.headers());
    }
}

服务器:

import http.handlers.EchoHandler;
import org.rapidoid.config.Conf;
import org.rapidoid.setup.On;

public class HttpServer {


    public static void start() {
        Conf.HTTP.set("serverName", Defaults.SERVER_NAME);
        Conf.HTTP.set("maxPipeline", Defaults.MAX_PIPELINE);
        On.get("/echo").managed(false).json(EchoHandler::handleEcho);
   }
}

现在尝试在Clojure中做同样的事情:

(ns harrow.http
  (:require
    ; harrow
    ; external
    [clojure.tools.logging  :as log       ] )
  (:import
    [org.rapidoid.config    Conf              ]
    [org.rapidoid.setup     On OnRoute        ]
    [org.rapidoid.http.impl RouteOptions      ]
    [org.rapidoid.http      Req               ]
    [org.rapidoid.u         U                 ]
    [java.util              Map LinkedHashMap ] ) )

(gen-class
  :name harrow.EchoHandler
  :methods [ #^{:static true} [handleEcho [org.rapidoid.http.Req] java.util.Map]] )
(defn -handleEcho ^Map [^Req req] (U/map (.headers req)))

使用它:

harrow.main=> (def config-get-route (http/set-http-get-route "/echo"))
harrow.main=> (import harrow.EchoHandler)
harrow.EchoHandler
harrow.main=> (.json config-get-route EchoHandler/handleEcho)

CompilerException java.lang.RuntimeException: Unable to find static field: handleEcho in class harrow.EchoHandler, compiling:(/private/var/folders/nr/g50ld9t91c555dzv91n43bg40000gn/T/form-init16236167396076700327.clj:1:1)

我想知道在Clojure中使用静态方法的正确方法是什么。

1 个答案:

答案 0 :(得分:4)

首先,您不能将静态方法作为函数传递-您本来可以 将其包装在anon-fn中。

此外,这也不起作用,因为该框架期望 实例实现某些接口。从Java8开始,您可以编写 如果只是接口,则作为lambdas和javac可以填补空白 有一种方法。

因此您不能简单地传入Clojure函数,该函数实现了 IFnRunnable,但那里不需要那个特定的接口。所以 您将需要从文档中查找内容,允许的内容和reify

例如使用Rapidoid 5.5.5时,看起来可能像这样:

(ns try-rapidoid.core
  (:import (org.rapidoid.http ReqHandler)
           (org.rapidoid.setup On Setup)))

(def echo-route
  (doto
    (On/get "/echo")
    (.managed true)
    (.json (reify ReqHandler ; XXX
             (execute [this ^Object req]
               (.headers req))))))

#_(Setup/shutdownAll)