Clojure中函数名前面的-(减号)是什么意思?

问题描述 投票:2回答:2

我无法理解以下内容。在Clojure中定义主要功能(基于Leinigen生成的代码)时,在功能名称-前面有一个main符号。

我去了clojure.com上的原始文档,发现defndefn-等,请参阅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
2个回答
0
投票

[所有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实例的静态方法。


0
投票

@ bfabry在大多数情况下是正确的,但在-(hypen)的含义上是错误的。


首先,放在一边。

defndefn-。第二种形式只是“私有”功能的简写,长形式如下:

(defn ^:private foo [args] ...)

但是,这只是向用户提示不要使用这些功能。解决此弱限制很容易进行测试等。由于麻烦,我从不使用所谓的“私有”功能(有时我会使用元数据^:no-doc和类似foo-impl的名称来表示fn不属于面向公众的API)。


Clojure已经采用了convention,在程序的主要入口点添加了连字符前缀。为此功能使用名称main也是常规,并且不是必需的。

您可以看到hypen约定的起源的一部分

© www.soinside.com 2019 - 2024. All rights reserved.