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


当前回答

如果您担心符号的拼写错误,请确保您的代码在访问具有不存在键的值时引发异常。你可以使用fetch而不是[]:

my_value = my_hash.fetch(:key)

或者在默认情况下,如果你提供了一个不存在的键,让哈希抛出一个异常:

my_hash = Hash.new do |hash, key|
  raise "You tried to access using #{key.inspect} when the only keys we have are #{hash.keys.inspect}"
end

如果散列已经存在,你可以添加异常引发行为:

my_hash = Hash[[[1,2]]]
my_hash.default_proc = proc do |hash, key|
  raise "You tried to access using #{key.inspect} when the only keys we have are #{hash.keys.inspect}"
end

通常情况下,您不必担心常量的拼写安全问题。如果你拼错了常量名,通常会引发异常。

其他回答

有人走在前面,写了一个红宝石宝石叫Renum。它声称获得了最接近Java/ c#的行为。就我个人而言,我仍然在学习Ruby,当我想让一个特定的类包含一个静态枚举(可能是一个散列)时,我有点震惊,因为它不太容易通过谷歌找到。

这完全取决于你如何使用Java或c#枚举。如何使用它将决定您在Ruby中选择的解决方案。

尝试本机Set类型,例如:

>> enum = Set['a', 'b', 'c']
=> #<Set: {"a", "b", "c"}>
>> enum.member? "b"
=> true
>> enum.member? "d"
=> false
>> enum.add? "b"
=> nil
>> enum.add? "d"
=> #<Set: {"a", "b", "c", "d"}>

查看ruby-enum gem, https://github.com/dblock/ruby-enum。

class Gender
  include Enum

  Gender.define :MALE, "male"
  Gender.define :FEMALE, "female"
end

Gender.all
Gender::MALE

符号是红宝石之道。然而,有时我们需要与一些C代码或Java进行对话,这些代码或Java会为各种事情公开一些枚举。


#server_roles.rb
module EnumLike

  def EnumLike.server_role
    server_Symb=[ :SERVER_CLOUD, :SERVER_DESKTOP, :SERVER_WORKSTATION]
    server_Enum=Hash.new
    i=0
    server_Symb.each{ |e| server_Enum[e]=i; i +=1}
    return server_Symb,server_Enum
  end

end

然后可以这样使用


require 'server_roles'

sSymb, sEnum =EnumLike.server_role()

foreignvec[sEnum[:SERVER_WORKSTATION]]=8

这当然可以是抽象的,你可以滚动我们自己的Enum类

我实现过这样的枚举

module EnumType

  def self.find_by_id id
    if id.instance_of? String
      id = id.to_i
    end 
    values.each do |type|
      if id == type.id
        return type
      end
    end
    nil
  end

  def self.values
    [@ENUM_1, @ENUM_2] 
  end

  class Enum
    attr_reader :id, :label

    def initialize id, label
      @id = id
      @label = label
    end
  end

  @ENUM_1 = Enum.new(1, "first")
  @ENUM_2 = Enum.new(2, "second")

end

然后很容易做操作

EnumType.ENUM_1.label

...

enum = EnumType.find_by_id 1

...

valueArray = EnumType.values