我无法理解以下内容。在Clojure中定义主要功能(基于Leinigen生成的代码)时,在功能名称-
前面有一个main
符号。
我去了clojure.com上的原始文档,发现defn
和defn-
等,请参阅https://clojuredocs.org/search?q=defn。我也在Google上进行搜索,找到了一个消息,该消息说main前面的-
表示该函数是静态(http://ben.vandgrift.com/2013/03/13/clojure-hello-world.html)。
-
确实表示该函数是静态的吗?我找不到其他证实这一点的消息来源。调用main方法时,我也可以同时使用(main)
和(-main)
。
给出以下代码...
(defn -main
"I don't do a whole lot ... yet."
[& args]
(println "Hello, World!"))
(defn main
"I don't do a whole lot ... yet."
[& args]
(println "Hello, World!"))
我得到以下输出...
(main)
Hello, World!
=> nil
(-main)
Hello, World!
=> nil
Loading src/clojure_example/core.clj... done
(main)
Hello, World!
=> nil
(-main)
Hello, World!
=> nil
我没有发现差异。这两个函数的输出相同。任何帮助表示赞赏!
[所有Clojure功能都是“静态”的(下面的题述)。在函数名称中放置-作为第一个字符不会对函数的行为产生任何影响。使用defn-
宏而不是defn
使函数私有。 -main
是~~约定〜Clojure程序的主要入口点的名称,如果在项目定义中将ns指定为“ main”命名空间,则Clojure运行时将查找名为-main
的函数并调用它。
我现在考虑的不是真的“按惯例”。由于它是不可更改的。这是主入口点可以拥有的唯一名称。
https://clojure.org/reference/repl_and_main
所有clojure函数实际上都是Java对象AFunction的实例,带有实例方法invoke
。因此从Java的角度来看它们不是静态的,但是在Clojure中,我会说它们是静态的,因为它们没有您看到的实例。 gen-class也有特殊情况,您可以使用clojure定义Java类。在这种情况下,您可以将生成的java类的clojure函数标记为^:static。这会在生成的Java类中创建一个引用AFunction实例的静态方法。
@ bfabry在大多数情况下是正确的,但在-
(hypen)的含义上是错误的。
宏defn
与defn-
。第二种形式只是“私有”功能的简写,长形式如下:
(defn ^:private foo [args] ...)
但是,这只是向用户提示不要使用这些功能。解决此弱限制很容易进行测试等。由于麻烦,我从不使用所谓的“私有”功能(有时我会使用元数据^:no-doc
和类似foo-impl
的名称来表示fn不属于面向公众的API)。
Clojure已经采用了convention,在程序的主要入口点添加了连字符前缀。为此功能使用名称main
也是常规,并且不是必需的。
您可以看到hypen约定的起源的一部分