clojure - 从 Java 调用 Clojure:为什么“新”样式 (clojure.java.api.Clojure) 比“旧”样式 (gen-class) 更好?
问题描述
在阅读了对相关问题的这个很好的答案后,有些事情让我感到困惑:
有两种可能性可以与 Java 开发人员共享我在 Clojure 中编写的函数
第一个是在 JAR 文件中提供它,以便他们可以调用它,就像我用 Java 编写的一样。听起来很适合 Clojure 宣传。
第二种方法,据称是更好的方法,要求那些 Java 开发人员使用类似
clojure.lang.IFn
or的东西,clojure.lang.RT
并通过将函数的名称作为字符串 (!) 传递来调用函数,而不仅仅是调用它们。
为什么第二种方法“更好”?
解决方案
你在这里设置了一个错误的二分法。每种方法都涉及创建一个 jar 文件:这就是 JVM 程序的分布方式。但是 Java 代码有 3 种不同的方式来调用 jar 中包含的 Clojure 代码:
- 使用 clojure.lang.RT 中的方法来初始化运行时,加载文件,然后查找 var。这是旧的,已弃用的方法。
- 使用 clojure.java.api.Clojure 中的方法来查找函数并调用它们。这是 (1) 的较新版本,隐藏了一些您可能不小心弄错的杂乱内容。
- 使用 Clojure 库中的 gen-class 为 Clojure 函数定义对 Java 更友好的接口。
您仍然可以执行 (3) - 完全没有问题。但是 gen-class 是一个相当笨重的工具,除了最简单的例子,比如暴露一些静态方法,它并不是很有趣,而且使用 Clojure 提供一个“感觉”像 Java API 的 API 也不容易.
但是你知道在提供一个感觉像 Java 的 API 方面有什么好处吗?爪哇!因此,如果您想让 Clojure 库在 Java 中易于使用,我建议您在 Clojure 库中包含一些 Java 代码。由您编写的 Java 代码弥合了语言鸿沟。它通过上述机制 (2) 访问您的 Clojure 代码,并呈现一个 Java 友好的外观,因此外部世界不必知道下面有 Clojure。
amalloy/thrift-gen是我多年前按照这种方法编写的库的一个示例。用纯 Clojure 编写它一点也不容易,因为传统的 Java 习惯用法对 Clojure 来说非常陌生,而且它不能很好地支持它们。通过编写我自己的 Java shim,Java 客户端获得了一个非常舒适的界面来使用,而且我可以编写感觉像 Clojure 的 Clojure,而不是一堆 gen 类的废话。
推荐阅读
- matlab - 在 MATLAB 中使用 predict() 时出现“未指定有效系统或数据集”
- python - 如何获取python顶层程序的顶层变量列表?
- python - 您如何获得通过数据框中的值搜索的特定值?
- ios - 线程 1:EXC_BAD_ACCESS(代码=1,地址=0x8000000000000010)
- vmware - 无法将 vmware-ovftool 放入卸载列表
- postgresql - 在触发器内调用的 postgres 函数中的 select 语句
- node.js - 使用 Angular CLI 反向代理 API Gateway/lambda 中的服务
- php - 建立数据库连接时遇到ERROR 404 url not found
- python - python isspace()的完整实现在哪里?
- qt - 调用 glewInit() 时 Qt QOpenGLWidget 崩溃并出现错误:缺少 GL 版本