枚举和Clojure

Enums and Clojure

在Java / C世界中,人们经常使用枚举。 如果使用的Java库使用枚举,则可以在它们和关键字之间进行转换,例如,使用(. java.lang.Enum valueOf e..., (aget ^"[Ljava.lang.Enum;" (. e (getEnumConstants)) i)和一些反射。 但是在Clojure世界中,人们是否需要像枚举(命名为整数)之类的东西? 如果不是,他们的代码结构如何使其不需要它们? 如果是,等价的是多少? 我觉得我真的在问索引(用于循环),在函数编程中很少使用索引(到目前为止,我仅使用map-indexed一次)。


正如Arthur所指出的那样,在Clojure中通常使用关键字代替枚举。

您不会看到编号索引使用过多-在Clojure(或大多数其他函数式编程语言)中它们并不是特别惯用的

其他一些值得注意的选择:

  • 直接使用Java枚举-例如java.util.concurrent.TimeUnit/SECONDS
  • 如果需要数值,请使用vars定义自己的常量-例如(def ^:const PURPLE 1)
  • 如果您想要使用简单语法的更高级枚举功能,甚至可以实现宏defenum


我见过的几乎所有Clojure代码都倾向于使用关键字而不是Enums,它们使用名称分隔,并具有关键字的所有其他有用属性,同时更容易编写。它们不是确切的替代者,因为它们比Java枚举更具动态性(例如在动态类型中)

至于索引和循环,我发现映射一系列关键字更为习惯:

1
(map do-stuff [:a :b :c :d] (range))

而不是遍历枚举中的值,尽管很有可能存在示例,但我还没有找到Clojure代码中的示例;


是的,在Java程序员使用枚举的大多数地方都使用关键字。在极少数情况下,您每个人都需要一个数字的情况,您只需定义一个转换映射:{:dog 0, :rabbit 1, ...}

另一方面,我编写的第一个Clojure库就是这样的:一个defenum宏,它为符号分配数字并来回创建转换系统。这是一个糟糕的想法,如果实施得当,请放心看看,但我不建议您使用它。