Использование статических методов из Clojure - PullRequest
0 голосов
/ 11 декабря 2018

Я пытаюсь реализовать в 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 голосов
/ 12 декабря 2018

Прежде всего, вы не можете передать статический метод как функцию - вы должны будете обернуть его в anon-fn.

Кроме того, это не будет работать, потому что эта структура ожидает экземплярытам реализуют определенные интерфейсы.Начиная с Java8, вы можете написать это как лямбды и javac, чтобы заполнить пробелы для вас, если интерфейс имеет только один метод.

Таким образом, вы не можете просто передать функцию Clojure, которая реализует, например, IFn иRunnable, но не тот конкретный интерфейс, необходимый там.Таким образом, вам придется посмотреть вверх из документов, что разрешено и 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...