7

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

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

(我知道其他方法很简单。您可以按 Gen-class 生成 .class ,就像它在Can you mix the JVM languages? 中所写的那样?即:Groovy 和 Clojure,但这只是允许您使用其他语言的 clojure。)

4

2 回答 2

12

由于 Clojure 在 JVM 上运行,因此您可以访问 Clojure 之外的类路径中的任何已知类。这是一个 Scala 示例。为了使类路径设置和依赖管理更容易,使用 Leiningen 生成一个项目。

lein new clojure-scala

在项目文件夹中,修改 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 编译类。现在运行lein deps下载依赖项。通过运行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 互操作性

使用 Java 中的 Scala 类可能会很棘手,尤其是当您的 Scala 类使用泛型、多态方法或抽象类型等高级特性时。由于 Java 没有这样的语言特性,因此您必须对 Scala 类的编码方案有所了解。

于 2012-08-21T11:24:58.803 回答
6

从 Clojure 调用其他 JVM 语言非常容易——您需要做的就是使用Java 互操作语法。

例子:

;; 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 语言)

于 2012-08-21T11:25:43.717 回答