如何从clojure很好地调用其他JVM语言?

如何从clojure很好地调用其他JVM语言?,clojure,Clojure,有时,您需要将用不同JVM语言编写的解决方案粘合在一起。为此,您需要调用该语言或以某种方式使用java位代码。在Clojure中,最纯粹、最安全、最美好的方式是什么 例如,从Clojure调用Scala的最佳方式是什么 (我知道另一种方法很简单。您可以在编写时逐个生成.class,但这只允许您从其他语言使用clojure。)由于clojure在JVM上运行,您可以访问clojure之外的类路径上的任何已知类。下面是一个Scala示例。为了简化类路径设置和依赖关系管理,请使用Leiningen生成

有时,您需要将用不同JVM语言编写的解决方案粘合在一起。为此,您需要调用该语言或以某种方式使用java位代码。在Clojure中,最纯粹、最安全、最美好的方式是什么

例如,从Clojure调用Scala的最佳方式是什么


(我知道另一种方法很简单。您可以在编写时逐个生成.class,但这只允许您从其他语言使用clojure。)

由于clojure在JVM上运行,您可以访问clojure之外的类路径上的任何已知类。下面是一个Scala示例。为了简化类路径设置和依赖关系管理,请使用Leiningen生成一个项目

lein new clojure-scala
在project文件夹中,修改project.clj并将Scala语言库的依赖项和Scala src文件夹添加到类路径:

(defproject clj-scala "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [[org.clojure/clojure "1.3.0"]
                 [org.scala-lang/scala-library "2.7.1"]]
  :compile-path "scala-src" )
创建目录scala src,并在该文件夹中创建以下scala类:

class HelloWorld {
  def sayHelloToClojure(msg: String) =
    "Here's the echo message from Scala: " concat msg
}
使用scalac编译该类。现在运行leindeps下载依赖项。通过运行lein REPL启动Clojure REPL。您可以导入Scala类,实例化它并调用sayHelloToClojure方法

user=> (import HelloWorld)
HelloWorld
user=> (.sayHelloToClojure (HelloWorld.) "Hi there")
"Here's the echo message from Scala: Hi there"
这与使用Scala类和Java代码的方式完全兼容。这可能会变得很棘手,引自:

使用Java中的Scala类可能会变得棘手,尤其是在 Scala类使用了诸如泛型、多态方法、, 或抽象类型。因为Java没有这样的语言特性,所以 必须了解Scala类的编码方案


从Clojure调用其他JVM语言非常容易——您只需使用语法即可

示例:

;; import Java classes
(ns my-ns
  (:import [some.package ClassOne ClassTwo ClassThree]))

;; call a regular method on an object
(.method someObject arg1 arg2)

;; call a constructor
(ObjectToConstuct. arg1 arg2)

;; call a static method
(Math/floor 2.3)

;; Use a static field
(+ 2 Math/PI)

基本上,使用这些技术,您可以调用任何其他创建JVM类的语言(包括Java、Scala和可能大多数其他JVM语言)

没有任何
最佳方法
,如果您正在寻找一种从Clojure中交互式地评估Scala的方法(通过嵌入Scala环境),那么一切都取决于
context
,这在技术上是可能的;但即使在这种情况下,Scala也必须编译和加载一个类。之所以使用Scala-lang依赖项,是因为当Scala库不在类路径中时,Java——因此Clojure——无法实例化Scala类。