在Ruby中实现枚举习惯用法的最佳方式是什么?我正在寻找一些我可以(几乎)使用的东西,比如Java/C#枚举。
发布于 2008-09-16 19:32:30
两种方式。符号(:foo
表示法)或常量(FOO
表示法)。
当您想要增强可读性而又不想在代码中乱丢文字字符串时,符号是合适的。
postal_code[:minnesota] = "MN"
postal_code[:new_york] = "NY"
当您有一个重要的基础值时,常量是合适的。只需声明一个模块来保存您的常量,然后在其中声明常量。
module Foo
BAR = 1
BAZ = 2
BIZ = 4
end
flags = Foo::BAR | Foo::BAZ # flags = 3
新增2021-01-17
如果要传递枚举值(例如,将其存储在数据库中),并且需要能够将值转换回符号,则这两种方法都有一个混搭
COMMODITY_TYPE = {
currency: 1,
investment: 2,
}
def commodity_type_string(value)
COMMODITY_TYPE.key(value)
end
COMMODITY_TYPE[:currency]
这种方法的灵感来自安德鲁-格林的答案https://stackoverflow.com/a/5332950/13468
我还建议通读这里的其余答案,因为有很多方法可以解决这个问题,这实际上归结为您所关心的另一种语言的枚举是什么
发布于 2011-05-30 05:19:59
令我惊讶的是,没有人提供这样的东西(从RAPI gem中收获):
class Enum
private
def self.enum_attr(name, num)
name = name.to_s
define_method(name + '?') do
@attrs & num != 0
end
define_method(name + '=') do |set|
if set
@attrs |= num
else
@attrs &= ~num
end
end
end
public
def initialize(attrs = 0)
@attrs = attrs
end
def to_i
@attrs
end
end
它可以像这样使用:
class FileAttributes < Enum
enum_attr :readonly, 0x0001
enum_attr :hidden, 0x0002
enum_attr :system, 0x0004
enum_attr :directory, 0x0010
enum_attr :archive, 0x0020
enum_attr :in_rom, 0x0040
enum_attr :normal, 0x0080
enum_attr :temporary, 0x0100
enum_attr :sparse, 0x0200
enum_attr :reparse_point, 0x0400
enum_attr :compressed, 0x0800
enum_attr :rom_module, 0x2000
end
示例:
>> example = FileAttributes.new(3)
=> #<FileAttributes:0x629d90 @attrs=3>
>> example.readonly?
=> true
>> example.hidden?
=> true
>> example.system?
=> false
>> example.system = true
=> true
>> example.system?
=> true
>> example.to_i
=> 7
在数据库场景中,或者在处理C风格的常量/枚举时(就像使用FFI时一样,RAPI被广泛使用),这一点发挥得很好。
而且,您不必像使用散列类型的解决方案那样担心输入错误会导致静默失败。
发布于 2008-09-16 19:06:05
最常用的方法是使用符号。例如,而不是:
enum {
FOO,
BAR,
BAZ
}
myFunc(FOO);
...you只能使用符号:
# You don't actually need to declare these, of course--this is
# just to show you what symbols look like.
:foo
:bar
:baz
my_func(:foo)
这比枚举更具开放性,但它非常符合Ruby精神。
符号的性能也很好。例如,比较两个符号是否相等要比比较两个字符串快得多。
https://stackoverflow.com/questions/75759
复制相似问题