Clojure:我如何需要一个类并调用静态方法?

时间:2015-11-20 07:39:41

标签: clojure

刚进入Clojure,我在命名空间,路径和类语法方面遇到了一些麻烦。

我开始测试并编写一个简单的hello world函数。

测试/ test_subject_test.clj:

(ns test-subject-test
  (:require [clojure.test :refer :all]
            [test-subject :refer :all]))

(deftest testit
  (testing "All good?"
    (is (= "I got this" (subject))))

的src / test_subject.clj:

(ns test-subject)

(defn subject []
  "I got this")

一切正常,所以我决定尝试在下一个类上调用静态方法。

测试/ test_subject_test.clj:

(ns test-subject-test
  (:require [clojure.test :refer :all]
            [test-subject :refer :all]
            [hello :refer :all]))

(deftest testit
  (testing "All good?"
    (is (= "I got this" (subject))))
  (testing "Try calling a static method"
    (is (= "Hello Guy!" (-handler Hello "Guy")))))

的src / hello.clj:

(ns hello
  (:gen-class :name "Hello"
              :methods [^:static [handler [String] String]]))

(defn -handler [s]
  (str "Hello " s "!"))

但是现在编译器会抛出一个长堆栈跟踪,其中包含一条有趣的消息:Caused by: java.lang.RuntimeException: Unable to resolve symbol: Hello in this context。我尝试了:require语句和(-handler Hello)调用的一些排列,我尝试过不使用:refer :all并将方法称为(-handler (.Hello hello)),但显然我是我遗漏了一些关于课程如何在Clojure中工作的基本信息。

我看了一下Clojure vars and Java static methods,但是对于我想要做的事情来说,这似乎比必要的要复杂得多:只需要调用一个静态方法。但是,问题中有一个有趣的引用,这导致我尝试这个:(Hello handler "Guy")没有成功(无法在此上下文中解析符号:Hello)。

那么,我应该如何从另一个文件中获取一个类并在其上调用静态方法?

2 个答案:

答案 0 :(得分:3)

如果您有静态方法,则应使用/分隔符调用它。

例如:

(System/currentTimeMillis)    

在您的情况下,以下内容应该有效:

(ns other
  (:require [hello :as hello]))

(hello/-handler "FOO")
; => "Hello FOO!"

供参考:http://clojure.org/java_interop

答案 1 :(得分:2)

如果您正在将一个类编译到默认包中(这是您在此处所做的),所有这些略有不同,因为您无法导入这些类。我不建议你那样做。在下面的代码中,我假装你实际上写了(:gen-class :name "hello.Hello" ...)

要在java类上调用方法,您应该使用完全限定的类名,或者首先使用import类:

(import 'hello.Hello)
(Hello/handler "there")

(hello.Hello/handler "there")

如您所见,您应该使用/来调用java类上的静态方法。

为了使这一切能够与gen-class一起工作,你必须确保首先编译类。保证 首先是require其命名空间的最简单方法是:

(require 'hello)
(import 'hello.Hello)

因为这比使用普通的clojure函数更麻烦。命名空间,如果您只打算从clojure调用代码,那么可能不应该使用java互操作。