当我第一次开始使用 Clojure 时,我也遇到过类似的问题。我几年前做过一些 Java 开发,但对那里的库仍然很不熟悉。
Intro
我发现使用 Java 最简单的方法就是不really用它。我认为对于刚开始使用 Clojure 中的 Java 来说,一本书有点太多了。除非您真正开始深入了解 JVM/Java 库,否则您真正需要了解的并不多。让我解释。
花更多时间学习如何从内到外使用 Clojure,并熟悉 Clojure-Contrib。例如,sqrt
位于 generic.math-functions 中 http://richhickey.github.com/clojure-contrib/generic.math-functions-api.html#clojure.contrib.generic.math-functions/sqrt在 Clojure.contrib 中。
事实上,您需要的许多东西已经在 Clojure 中了,但还有很多东西还没有。
熟悉 Clojure 中的调用约定和语法糖以使用 Java。例如Math/sqrt
根据您的示例,正在调用静态方法(基本上只是一个函数)sqrt
从班级Math
.
无论如何,如果您发现自己有问题,这里有一份指南可以帮助您入门really需要使用Java。我假设你已经完成了some命令式面向对象编程,但仅此而已。即使你没有,你也应该没问题。
Isaac 的 Java Clojurist 指南
Classes
类是一组方法(作用于类的函数),
也可以是数据类型:例如创建该类型的新类Double
: (Double. 1.2)
它使用值初始化 Double 类(句点是调用类构造函数方法的语法糖,该方法使用您提供的值初始化类)1.2
.
现在,看看Double class http://download-llnw.oracle.com/javase/6/docs/api/java/lang/Double.html在 Java 6 API 中:
Double
public Double(double value)
Constructs a newly allocated Double object that represents the
primitive double argument.
Parameters:
value - the value to be represented by the Double.
所以你可以看到那里发生了什么。你“建造”了一个新的Double
有价值1.2
,这是一个双精度数。那里有点令人困惑,但实际上 Double 是一个代表 Double 的类,并且可以执行与 double 相关的操作。
静态方法
例如,要从字符串中解析出 Double 值,我们可以使用静态方法(这意味着我们不需要特定的实例)Double
,我们可以像我们调用的那样调用它sqrt
) parseDouble(String s)
:
(Double/parseDouble "1.2") => 1.2
那里并不棘手。
非静态方法
假设我们想要使用一个已初始化的 Java 类。不太难:
(-> (String. "Hey there") ;; make a new String object
(.toUpperCase)) ;; pass it to .toUpperCase (look up -> to see what it does)
;; toUpperCase is a non-static method
=> "HEY THERE"
所以现在我们使用了一种非静态的方法,它需要一个真实的、实时的String
处理的对象。让我们看看文档是如何工作的:
toUpperCase
public String toUpperCase()
Converts all of the characters in this String to upper case using
the rules of the default locale. This method is equivalent to
toUpperCase(Locale.getDefault()).
Returns:
the String, converted to uppercase.
所以这里我们有一个返回字符串的方法(如定义中 public 后面的“String”所示,并且不带任何参数。但是等等!它确实需要一个参数。在 Python 中,它将是隐式参数self
: 这就是所谓的this
在爪哇。
我们还可以使用这样的方法:(.toUpper (String. "Hey there"))
并得到相同的结果。
有关方法的更多信息
由于您在 Java 中处理可变数据和类,因此您需要能够将函数应用于类(实际上是类的实例)并且不期望返回值。
例如,假设我们正在处理一个JFrame
来自javax.swing
图书馆。我们可能需要做很多事情to它不是with it(你一般操作with价值观,不on它们是函数式语言)。我们可以这样:
(doto (JFrame. "My Frame!");; clever name
(.setContentPane ... here we'd add a JPanel or something to the JFrame)
(.pack) ;; this simply arranges the stuff in the frame–don't worry about it
(.setVisibleTrue)) ;; this makes the Frame visible
doto
只是将其第一个参数传递给您提供的所有其他函数,并将其作为第一个参数传递给它们。所以我们在这里做了很多事情to the JFrame
不会返回任何特别的东西。所有这些方法都被列为JFrame
在文档中(或其超类......还不用担心这些)。
包起来
这应该让你为现在的探索做好准备Java文档 http://download-llnw.oracle.com/javase/6/docs/api/你自己。在这里您将找到标准 Java 1.6 安装中可用的所有内容。将会有新的概念,但是快速的谷歌搜索应该可以回答您的大部分问题,并且您可以随时带着具体的问题回到这里。
请务必研究其他重要的 Clojure 函数,例如proxy
and reify
也extend-type
和它的朋友。我不经常使用它们,但当我需要时,它们可能是无价的。事实上,我自己仍然在理解它们。
那里有很多,但主要是数量问题而不是复杂性问题。这并不是一个坏问题。
补充阅读:
-
静态还是非静态? http://cscie160-distance.com/nonstatic.html;;静态与非静态方法指南
-
Java 类库 http://en.wikipedia.org/wiki/Java_Class_Library;;带有精美图片的概述
-
Java文档 http://download-llnw.oracle.com/javase/6/docs/api/;;上面链接
-
Clojure Java 互操作文档 http://clojure.org/java_interop;;来自 Clojure 网站
-
最佳 Java 书籍 https://stackoverflow.com/questions/75102/best-java-book-you-have-read-so-far;;根据克拉塔克的回答