编译

当clojure的源代码文件被当作脚本文件执行的时候,它们是在运行时被编译成java的bytecode的。同时我们也可以提前编译(AOT ahead-of-time)它们成java bytecode。这会缩短clojure程序的启动时间,并且产生的.class文件还可以给java程序使用。我们推荐按照下面的步骤来做:

  1. 为你要编译的文件选择一个名字空间,比如: com.ociweb.talk
  2. 在父目录里面创建两个目录: " src " 和 " classes " 。
  3. 使你的其中一个文件的文件名和包名的最后一段相同,比如: talk.clj
  4. 把你的源文件放在 " src " 目录下面,并且创建和名字空间一样的目录层级,比如: src/com/ociweb/talk.clj
  5. 在你的源代码的最上面给你的文件指定名字空间,并且包含:gen-class标记: (ns com.ociweb.talk (:gen-class))
  6. 在你的主源文件里面,使用 load 函数来加载同一个目录下面的其它源文件, 比如,如果 more.clj 在目录 src/com/ociweb 的子目录 " talk "下面那么用这个语句来加载 (load "talk/more") .
  7. 在其它的源文件里面, 使用 in-ns 函数来设置他们的名字空间. 比如, 在more.clj文件上面指定名字空间: (in-ns 'com.ociweb.talk)。
  8. 把 " src " 和 " classes " 目录添加到REPL的classpath里面去。如果你使用了一个脚本来运行REPL, 那么修改那个脚本。
  9. 启动一个REPL。
  10. 使用 compile 函数来编译一个给定名字空间的clojure文件: (compile '_namespace_)。比如 : (compile 'com.ociweb.talk) .

这些步骤会为每个函数创建一个单独的.class文件。他们会被写到 " classes " 文件夹下对应的子文件夹下面去。

如果这个被编译的名字空间有一个叫做- main 的函数, 那么你可以把它当作java的主类的运行。命令行参数会被当作参数传递给这个函数。比如,如果 talk.clj 包含一个叫 -main 的函数, 你可以用下面的命令来运行:

java -classpath <em>path</em>/classes:<em>path</em>/clojure.jar com.ociweb.talk <em>args</em>