首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在Ruby中实现枚举?

如何在Ruby中实现枚举?
EN

Stack Overflow用户
提问于 2008-09-16 19:02:09
回答 22查看 209.7K关注 0票数 348

在Ruby中实现枚举习惯用法的最佳方式是什么?我正在寻找一些我可以(几乎)使用的东西,比如Java/C#枚举。

EN

回答 22

Stack Overflow用户

回答已采纳

发布于 2008-09-16 19:32:30

两种方式。符号(:foo表示法)或常量(FOO表示法)。

当您想要增强可读性而又不想在代码中乱丢文字字符串时,符号是合适的。

代码语言:javascript
复制
postal_code[:minnesota] = "MN"
postal_code[:new_york] = "NY"

当您有一个重要的基础值时,常量是合适的。只需声明一个模块来保存您的常量,然后在其中声明常量。

代码语言:javascript
复制
module Foo
  BAR = 1
  BAZ = 2
  BIZ = 4
end
 
flags = Foo::BAR | Foo::BAZ # flags = 3

新增2021-01-17

如果要传递枚举值(例如,将其存储在数据库中),并且需要能够将值转换回符号,则这两种方法都有一个混搭

代码语言:javascript
复制
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

我还建议通读这里的其余答案,因为有很多方法可以解决这个问题,这实际上归结为您所关心的另一种语言的枚举是什么

票数 347
EN

Stack Overflow用户

发布于 2011-05-30 05:19:59

令我惊讶的是,没有人提供这样的东西(从RAPI gem中收获):

代码语言:javascript
复制
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

它可以像这样使用:

代码语言:javascript
复制
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

示例:

代码语言:javascript
复制
>> 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被广泛使用),这一点发挥得很好。

而且,您不必像使用散列类型的解决方案那样担心输入错误会导致静默失败。

票数 60
EN

Stack Overflow用户

发布于 2008-09-16 19:06:05

最常用的方法是使用符号。例如,而不是:

代码语言:javascript
复制
enum {
  FOO,
  BAR,
  BAZ
}

myFunc(FOO);

...you只能使用符号:

代码语言:javascript
复制
# 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精神。

符号的性能也很好。例如,比较两个符号是否相等要比比较两个字符串快得多。

票数 52
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/75759

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档