刚进入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)。
那么,我应该如何从另一个文件中获取一个类并在其上调用静态方法?
答案 0 :(得分:3)
如果您有静态方法,则应使用/
分隔符调用它。
例如:
(System/currentTimeMillis)
在您的情况下,以下内容应该有效:
(ns other
(:require [hello :as hello]))
(hello/-handler "FOO")
; => "Hello FOO!"
答案 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互操作。