Clojure 为什么编译`*.clj`源代码也会执行代码?

Clojure 为什么编译`*.clj`源代码也会执行代码?,clojure,Clojure,我有以下非敏感的*.clj文件: (ns bar.zar.Foo (:gen-class :main true)) (println "foo") (defn -main [& args] nil) 使用以下Ant目标将其编译为*.class(clojure.lang.Compile)时: <target name="compile-clojure" description="Compile Clojure sources." depends="resolve"&g

我有以下非敏感的
*.clj
文件:

(ns bar.zar.Foo
  (:gen-class :main true))

(println "foo")

(defn -main [& args]
   nil)
使用以下Ant目标将其编译为
*.class
clojure.lang.Compile
)时:

<target name="compile-clojure" description="Compile Clojure sources." depends="resolve">
  <mkdir dir="${cljbuild.dir}"/>
  <java classname="clojure.lang.Compile"
        failonerror="true"
        fork="true">
    <classpath refid="compile.classpath"/>
    <sysproperty key="clojure.compile.path" value="${cljbuild.dir}"/>
    <arg value="${project.MainClass.name}"/>
  </java>
</target>

也就是说,编译期间对
(println“foo”)
表达式进行了评估。为什么呢?这与“Lisp模糊了编译时/运行时的区别”有关吗?

Clojure中的编译单元是顶级s表达式,它在加载文件时被读取、扩展、计算并经常存储在名称空间中。整个文件没有单独的编译阶段。这样做允许您编写定义其他函数、类型、DSL等的函数,并且是宏系统的构建块

将您不希望运行的任何内容放入init函数中,然后包括从main(或代码开始的任何地方)调用该函数

 [java] Compiling bar.zar.Foo to /home/[ommitted]/build
 [java] foo