如何在 Ruby 中实现枚举?

31 浏览
0 Comments

如何在 Ruby 中实现枚举?

什么是在Ruby中实现enum范例的最佳方式?我正在寻找类似于Java/C#enum的(几乎可以使用)东西。

admin 更改状态以发布 2023年5月23日
0
0 Comments

我很惊讶没有人提供像下面这样的东西(从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)
=> #
>> example.readonly?
=> true
>> example.hidden?
=> true
>> example.system?
=> false
>> example.system = true
=> true
>> example.system?
=> true
>> example.to_i
=> 7

在处理数据库场景或处理C样式的常量/枚举(当使用FFI时,RAPI广泛使用)时,这个方法非常有效。

此外,您不必担心打字错误导致静默失败,就像使用哈希类型解决方案一样。

0
0 Comments

有两种方式。符号(: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]

此方法受 andrew-grimm 的回答 https://stackoverflow.com/a/5332950/13468 的启发。

我还建议仔细阅读这里的其他答案,因为有很多解决方法,而且它真正关注的是您关心其他语言枚举的什么。

0