在Ruby中实现枚举习语的最佳方法是什么?我正在寻找一些东西,我可以使用(几乎)像Java/ c#枚举。
当前回答
这似乎有点多余,但这是我使用过几次的方法,特别是在集成xml或类似的方法时。
#model
class Profession
def self.pro_enum
{:BAKER => 0,
:MANAGER => 1,
:FIREMAN => 2,
:DEV => 3,
:VAL => ["BAKER", "MANAGER", "FIREMAN", "DEV"]
}
end
end
Profession.pro_enum[:DEV] #=>3
Profession.pro_enum[:VAL][1] #=>MANAGER
这给了我c#枚举的严谨性,并且它与模型绑定。
其他回答
另一种方法是使用带有包含名称和值的散列的Ruby类,如下面的RubyFleebie博客文章所述。这允许您轻松地在值和常量之间进行转换(特别是如果您添加了一个类方法来查找给定值的名称)。
两种方式。符号(: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的启发
我也建议阅读这里剩下的答案,因为有很多方法来解决这个问题,它实际上归结为你关心的其他语言的枚举
也许最好的轻量级方法是
module MyConstants
ABC = Class.new
DEF = Class.new
GHI = Class.new
end
这样,值就有了关联的名称,就像在Java/ c#中一样:
MyConstants::ABC
=> MyConstants::ABC
要获得所有的值,可以这样做
MyConstants.constants
=> [:ABC, :DEF, :GHI]
如果你想要枚举的序号值,你可以这样做
MyConstants.constants.index :GHI
=> 2
这是我在Ruby中处理枚举的方法。我想要的是简短而甜蜜的,不一定是最像c的。任何想法吗?
module Kernel
def enum(values)
Module.new do |mod|
values.each_with_index{ |v,i| mod.const_set(v.to_s.capitalize, 2**i) }
def mod.inspect
"#{self.name} {#{self.constants.join(', ')}}"
end
end
end
end
States = enum %w(Draft Published Trashed)
=> States {Draft, Published, Trashed}
States::Draft
=> 1
States::Published
=> 2
States::Trashed
=> 4
States::Draft | States::Trashed
=> 5
如果你使用的是Rails 4.2或更高版本,你可以使用Rails枚举。
Rails现在默认有枚举,不需要包含任何宝石。
这与Java、c++的枚举非常相似(并且具有更多的特性)。
引用自http://edgeapi.rubyonrails.org/classes/ActiveRecord/Enum.html:
class Conversation < ActiveRecord::Base
enum status: [ :active, :archived ]
end
# conversation.update! status: 0
conversation.active!
conversation.active? # => true
conversation.status # => "active"
# conversation.update! status: 1
conversation.archived!
conversation.archived? # => true
conversation.status # => "archived"
# conversation.update! status: 1
conversation.status = "archived"
# conversation.update! status: nil
conversation.status = nil
conversation.status.nil? # => true
conversation.status # => nil
推荐文章
- 是否可以在MiniTest中运行单个测试?
- 如何在Ruby中生成a和b之间的随机数?
- 我可以在Java中设置enum起始值吗?
- 无法安装gem -未能建立gem本地扩展-无法加载这样的文件——mkmf (LoadError)
- 如何在Ruby中创建文件
- 什么是Ruby文件。开放模式和选项?
- Ruby数组到字符串的转换
- 如何分割(块)一个Ruby数组成X元素的部分?
- Ruby中“or”和||的区别?
- c# vs Java Enum(适合c#新手)
- 如何测试参数是否存在在轨道
- 在Ruby中不创建新字符串而修饰字符串的规范方法是什么?
- RVM不是一个函数,用' RVM use…’不会起作用
- 了解Gemfile。锁文件
- 如何确定一个数组是否包含另一个数组的所有元素