在Ruby中实现枚举习语的最佳方法是什么?我正在寻找一些东西,我可以使用(几乎)像Java/ c#枚举。
当前回答
也许最好的轻量级方法是
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
其他回答
符号是红宝石之道。然而,有时我们需要与一些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类
我认为实现类似类型的枚举的最好方法是使用符号,因为它们的行为非常像整数(当涉及到性能时,object_id用于进行比较);你不需要担心索引,它们在你的代码xD中看起来非常整洁
我实现过这样的枚举
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
另一种解决方案是使用OpenStruct。它非常简单明了。
https://ruby-doc.org/stdlib-2.3.1/libdoc/ostruct/rdoc/OpenStruct.html
例子:
# bar.rb
require 'ostruct' # not needed when using Rails
# by patching Array you have a simple way of creating a ENUM-style
class Array
def to_enum(base=0)
OpenStruct.new(map.with_index(base).to_h)
end
end
class Bar
MY_ENUM = OpenStruct.new(ONE: 1, TWO: 2, THREE: 3)
MY_ENUM2 = %w[ONE TWO THREE].to_enum
def use_enum (value)
case value
when MY_ENUM.ONE
puts "Hello, this is ENUM 1"
when MY_ENUM.TWO
puts "Hello, this is ENUM 2"
when MY_ENUM.THREE
puts "Hello, this is ENUM 3"
else
puts "#{value} not found in ENUM"
end
end
end
# usage
foo = Bar.new
foo.use_enum 1
foo.use_enum 2
foo.use_enum 9
# put this code in a file 'bar.rb', start IRB and type: load 'bar.rb'
我知道自从那个人发布这个问题已经有很长时间了,但我也有同样的问题,这篇文章没有给我答案。我想要一种简单的方法来查看数字代表什么,便于比较,最重要的是ActiveRecord支持使用表示枚举的列进行查找。
我没有找到任何东西,所以我做了一个很棒的实现,叫做yinum,它允许我所寻找的一切。做了很多规格,所以我很确定它是安全的。
一些示例特性:
COLORS = Enum.new(:COLORS, :red => 1, :green => 2, :blue => 3)
=> COLORS(:red => 1, :green => 2, :blue => 3)
COLORS.red == 1 && COLORS.red == :red
=> true
class Car < ActiveRecord::Base
attr_enum :color, :COLORS, :red => 1, :black => 2
end
car = Car.new
car.color = :red / "red" / 1 / "1"
car.color
=> Car::COLORS.red
car.color.black?
=> false
Car.red.to_sql
=> "SELECT `cars`.* FROM `cars` WHERE `cars`.`color` = 1"
Car.last.red?
=> true
推荐文章
- 我如何在Ruby中解析YAML文件?
- Rails中的OO设计:在哪里放置东西
- Java:检查enum是否包含给定的字符串?
- 从Description属性中获取Enum
- 如何在c++中使用枚举
- 给定一个类,查看实例是否有方法(Ruby)
- 在日历应用程序中建模重复事件的最佳方法是什么?
- 如何创建一个私有类方法?
- 无法安装pg gem
- 双* (splat)操作符做什么
- 如何使用Ruby on Rails进行HTTP请求?
- 如何从rake任务中提前返回?
- 什么&。(&点)在Ruby中是什么意思?
- 是什么阻碍了Ruby和Python获得V8的Javascript速度?
- 运行pod设置给我“坏的解释器:没有这样的文件或目录”错误