我只想知道在 Ruby 中模拟 C# 样式枚举的最佳方法。
fooledbyprimes
问问题
2014 次
5 回答
5
不太一样,但我经常会为这种事情建立一个哈希:
STATES = {:open => 1, :closed => 2, :max => 3, :min => 4}.freeze()
冻结哈希可以防止我意外修改其内容。
此外,如果您想在访问不存在的内容时引发错误,您可以使用默认 Proc 来执行此操作:
STATES = Hash.new { |hash, key| raise NameError, "#{key} is not allowed" }
STATES.merge!({:open => 1, :closed => 2, :max => 3, :min => 4}).freeze()
STATES[:other] # raises NameError
于 2008-10-02T22:09:25.070 回答
5
具体来说,我希望能够针对给定某个变量的一组值执行逻辑测试。示例是窗口的状态:“最小化、最大化、关闭、打开”
如果您需要将枚举映射到值(例如,您需要最小化到等于 0,最大化到等于 100 等),我会使用符号哈希值,如下所示:
WINDOW_STATES = { :minimized => 0, :maximized => 100 }.freeze
冻结(就像 nate 说的那样)阻止你在未来意外破坏东西。您可以通过执行此操作来检查某些内容是否有效
WINDOW_STATES.keys.include?(window_state)
或者,如果您不需要任何值,而只需要检查“成员资格”,那么数组就可以了
WINDOW_STATES = [:minimized, :maximized].freeze
像这样使用它
WINDOW_STATES.include?(window_state)
如果您的键将是字符串(例如 RoR 应用程序中的“状态”字段),那么您可以使用字符串数组。我在我们的许多 Rails 应用程序中一直这样做。
WINDOW_STATES = %w(minimized maximized open closed).freeze
这几乎就是 Railsvalidates_inclusion_of
验证器的用途 :-)
个人备注:
我不喜欢打字包括?一直,所以我有这个(它只是因为 .in?(1, 2, 3) 情况而变得复杂:
class Object
# Lets us write array.include?(x) the other way round
# Also accepts multiple args, so we can do 2.in?( 1,2,3 ) without bothering with arrays
def in?( *args )
# if we have 1 arg, and it is a collection, act as if it were passed as a single value, UNLESS we are an array ourselves.
# The mismatch between checking for respond_to on the args vs checking for self.kind_of?Array is deliberate, otherwise
# arrays of strings break and ranges don't work right
args.length == 1 && args.first.respond_to?(:include?) && !self.kind_of?(Array) ?
args.first.include?( self ) :
args.include?( self )
end
end
end
这使您可以键入
window_state.in? WINDOW_STATES
于 2008-10-02T22:24:58.997 回答
3
我不认为 Ruby 支持真正的枚举——尽管如此,仍然有可用的解决方案。
于 2008-10-02T21:43:02.327 回答
3
在 ruby 中定义枚举以使用具有常量变量的类的最简单方法。
class WindowState
Open = 1
Closed = 2
Max = 3
Min = 4
end
于 2008-10-02T22:02:39.267 回答
1
于 2008-10-02T22:15:23.247 回答