在 Java/C 世界中,人们经常使用枚举。如果我使用的是使用枚举的 Java 库,我可以在它们和关键字之间进行转换,例如 using(. java.lang.Enum valueOf e..., (aget ^"[Ljava.lang.Enum;" (. e (getEnumConstants)) i)
和一些反射。但是在 Clojure 世界中,人们是否需要像枚举(命名整数)这样的东西?如果不是,他们的代码是如何构建他们不需要它们的?如果是,等价物是什么?我觉得我真的在问索引(用于循环),它在函数式编程中很少使用(到目前为止我只使用过一次 map-indexed)。
问问题
13755 次
3 回答
20
对于我见过的几乎所有 Clojure 代码,都倾向于使用关键字而不是枚举,它们是名称空间的,并且具有关键字的所有其他有用属性,同时更容易编写。它们不是一个精确的代表,因为它们比 Java 枚举更动态(如在动态类型中)
至于索引和循环,我发现映射一系列关键字更惯用:
(map do-stuff [:a :b :c :d] (range))
而不是循环枚举中的值,我还没有在 Clojure 代码中找到一个例子,尽管一个例子很可能存在;-)
于 2012-08-08T00:55:49.770 回答
20
正如Arthur 指出的那样- Clojure 中通常使用关键字代替枚举。
你不会看到编号索引被大量使用——它们在 Clojure(或大多数其他函数式编程语言)中并不是特别惯用的
其他一些值得注意的选项:
- 直接使用 Java 枚举 - 例如
java.util.concurrent.TimeUnit/SECONDS
- 如果您需要数值,请使用 vars 定义您自己的常量 - 例如
(def ^:const PURPLE 1)
defenum
如果您想要使用简单语法的更高级枚举功能,您甚至可以实现宏。
于 2012-08-08T05:24:16.770 回答
6
是的,在 Java 程序员使用枚举的大多数地方都使用关键字。在极少数情况下,您需要为它们中的每一个设置一个数字,您可以简单地定义一个用于转换的映射:{:dog 0, :rabbit 1, ...}
。
另一方面,我编写的第一个 Clojure 库就是这样:一个defenum
为符号分配数字并创建来回转换系统的宏。这是一个糟糕的想法,实施得相当好,所以随意看看,但我不建议你使用它。
于 2012-08-08T07:00:44.717 回答