mli*_*bby 305
两种方式.符号(:foo
符号)或常量(FOO
符号).
当您想要增强可读性而不使用文字字符串乱丢代码时,符号是合适的.
postal_code[:minnesota] = "MN"
postal_code[:new_york] = "NY"
Run Code Online (Sandbox Code Playgroud)
当您具有重要的基础值时,常量是合适的.只需声明一个模块来保存常量,然后在其中声明常量.
module Foo
BAR = 1
BAZ = 2
BIZ = 4
end
flags = Foo::BAR | Foo::BAZ # flags = 3
Run Code Online (Sandbox Code Playgroud)
Cha*_*les 58
我很惊讶没有人提供类似下面的东西(从RAPI宝石中收获):
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
Run Code Online (Sandbox Code Playgroud)
哪个可以这样使用:
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
Run Code Online (Sandbox Code Playgroud)
例:
>> 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
Run Code Online (Sandbox Code Playgroud)
这在数据库场景中或在处理C样式常量/枚举时都很好(当使用FFI时,RAPI大量使用它).
此外,您不必像使用散列类型解决方案那样担心会导致静默失败的拼写错误.
emk*_*emk 52
最常用的方法是使用符号.例如,而不是:
enum {
FOO,
BAR,
BAZ
}
myFunc(FOO);
Run Code Online (Sandbox Code Playgroud)
...你可以使用符号:
# 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)
Run Code Online (Sandbox Code Playgroud)
这比枚举更开放,但它与Ruby精神很吻合.
符号也表现得很好.例如,比较两个符号的相等性比比较两个字符串要快得多.
Ale*_*xey 35
我使用以下方法:
class MyClass
MY_ENUM = [MY_VALUE_1 = 'value1', MY_VALUE_2 = 'value2']
end
Run Code Online (Sandbox Code Playgroud)
我喜欢它具有以下优点:
MY_ENUM
MY_VALUE_1
符号可能更好,因为如果您在另一个类中使用它,则不必编写外部类的名称(MyClass::MY_VALUE_1
)
ved*_*ant 17
如果您使用的是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
Run Code Online (Sandbox Code Playgroud)
查看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
Run Code Online (Sandbox Code Playgroud)
小智 8
这是我在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
=> 3
Run Code Online (Sandbox Code Playgroud)
我知道自从这个人发布这个问题以来已经有很长一段时间了,但是我有同样的问题而且这篇帖子没有给我答案.我想要一种简单的方法来查看数字代表什么,简单的比较,以及大多数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
Run Code Online (Sandbox Code Playgroud)
另一种解决方案是使用 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'
Run Code Online (Sandbox Code Playgroud)
如果您担心带有符号的拼写错误,请确保在使用不存在的密钥访问值时代码会引发异常.你可以通过使用fetch
而不是[]
:
my_value = my_hash.fetch(:key)
Run Code Online (Sandbox Code Playgroud)
或者,如果提供不存在的密钥,则默认情况下使哈希引发异常:
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
Run Code Online (Sandbox Code Playgroud)
如果哈希已存在,则可以添加异常提升行为:
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
Run Code Online (Sandbox Code Playgroud)
通常,您不必担心常量的拼写错误.如果拼错常量名称,通常会引发异常.
也许最好的轻量级方法是
module MyConstants
ABC = Class.new
DEF = Class.new
GHI = Class.new
end
Run Code Online (Sandbox Code Playgroud)
这样,值具有关联的名称,如Java / C#中那样:
MyConstants::ABC
=> MyConstants::ABC
Run Code Online (Sandbox Code Playgroud)
要获取所有值,您可以执行
MyConstants.constants
=> [:ABC, :DEF, :GHI]
Run Code Online (Sandbox Code Playgroud)
如果您想要枚举的序数值,则可以执行
MyConstants.constants.index :GHI
=> 2
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
165518 次 |
最近记录: |