Clojure常量的约定,样式和用法?

时间:2010-08-26 20:07:21

标签: clojure

在样式,约定,效率等方面,在Clojure中定义常量的最佳实践是什么?

例如,这是对的吗?

(def *PI* 3.14)

问题:

常量应该在Clojure中大写吗?

在风格上,他们是否应该在一侧或两侧都有星号(*)?

我应该注意哪些计算效率考虑因素?

8 个答案:

答案 0 :(得分:41)

来自http://dev.clojure.org/display/community/Library+Coding+Standards

  

仅将 earmuffs 用于重新绑定的内容。 不要对常量使用特殊符号; 除非另有说明,否则所有内容都被视为常量。

答案 1 :(得分:23)

我认为没有任何硬性规定。我通常根本不给他们任何特殊待遇。在函数式语言中,常量和任何其他值之间的区别较小,因为事物往往更纯粹。

两侧的星号在Clojure中被称为“耳罩”。它们通常用于表示“特殊”var,或者稍后将使用绑定动态反弹的var。像 out 中的东西,偶尔会被用户反弹到不同的流中,这些都是例子。

就个人而言,我只会将其命名为pi。我不认为我曾经见过人们在Clojure中给常量赋予特殊名称。

编辑:Carper先生刚刚指出他自己在代码中使用常量,因为它是其他语言的惯例。我想这表明至少有一些人这样做。

我快速浏览了coding standards,但没有发现任何相关内容。这使我得出结论,无论你是否利用它们,都取决于你。从长远来看,我认为没有人会为你拍打它。

答案 2 :(得分:13)

在计算效率方面你应该知道在Clojure中没有全局常量这样的东西。你上面的是一个var,每次你引用它时,它都会进行查找。即使你没有把耳罩放在上面,变速器总是可以反弹,所以价值总是会改变,所以它们总是在桌子上查找。对于性能关键循环,这绝对是非最佳的。

有一些选项可以在你的关键循环周围放置一个let块,并让任何“常量”变量值保持不变。或者创建一个无参数宏,以便将常量值编译到代码中。或者您可以使用静态成员创建Java类。

请参阅此文章,以及有关常量的以下讨论以获取更多信息:

http://groups.google.com/group/clojure/msg/78abddaee41c1227

答案 3 :(得分:8)

耳罩是一种表示给定符号在某些时候具有自己的线程局部绑定的方式。因此,将耳罩应用于Pi常数是没有意义的。

*clojure-version*是Clojure中常量的一个例子,它完全是小写的。

答案 4 :(得分:4)

不要对常量使用特殊符号;除非另有说明,否则一切都假定为常数。

请参阅http://dev.clojure.org/display/community/Library+Coding+Standards

答案 5 :(得分:1)

Clojure有各种各样的文字,例如:

3.14159
:point
{:x 0 
 :y 1}
[1 2 3 4]
#{:a :b :c}

文字是不变的。据我所知,没有办法定义新的文字。如果要使用新常量,可以在编译时在代码中有效地生成文字:

(defmacro *PI* [] 3.14159265358979323)
(prn (*PI*))

答案 6 :(得分:1)

在Common Lisp中,有一个用加号(+my-constant+)命名常量的约定,在Scheme中,用一个美元符号($my-constant)加前缀;见this page。任何此类约定都与官方Clojure编码标准冲突,并与其他答案相关联,但也许将常规变量与使用:const属性定义的变量区分开来是合理的。

我认为赋予任何类型的非函数变量某种区别特征是有利的。假设除了定义为保存函数的变量之外,通常只使用由函数参数let等定义的本地名称。如果您偶尔使用def定义非函数变量,那么当它的名称时出现在同一文件的函数定义中,它看起来就像一个局部变量。如果函数很复杂,您可能需要花几秒钟时间在函数中查找名称定义。根据变量的使用情况添加耳罩或加号或全部大写等区别特征,可以明显看出变量的定义是在其他地方。

此外,有充分的理由给pi这样的特殊常量一个特殊名称,所以没有人不得不怀疑pi是否意味着“打印索引”,或者是第i个披萨,或者“保留界面”。当然认为这些变量应该有更多信息的名称,但很多人使用神秘的,简短的变量名称,我最终阅读他们的代码。我不应该怀疑pi是否意味着pi,所以像PI这样的东西可能有意义。没有人会认为这是Clojure中磨机变量的运行。

答案 7 :(得分:0)

根据“实用Clojure”一书,它应命名为*pi*