【问题标题】:How can I use C# style enumerations in Ruby?如何在 Ruby 中使用 C# 样式的枚举?
【发布时间】:2008-10-02 21:36:45
【问题描述】:

我只是想知道在 Ruby 中模拟 C# 样式枚举的最佳方法。

【问题讨论】:

  • 您在寻找哪些具体功能?你可以把一些符号放在一个数组中......
  • 具体来说,我希望能够针对给定变量的一组值执行逻辑测试。例如窗口的状态:“最小化、最大化、关闭、打开”。

标签: ruby enumeration language-construct


【解决方案1】:

具体来说,我希望能够针对给定变量的一组值执行逻辑测试。例如窗口的状态:“最小化、最大化、关闭、打开”

如果您需要将枚举映射到值(例如,您需要最小化为 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

这几乎就是 rails validates_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

【讨论】:

  • 注意:向 Object 添加实例方法可能很危险——这有点像向全局命名空间添加东西。往下看 Object#in?非常谨慎的道路。
【解决方案2】:

不太一样,但我会经常为这种事情建立一个哈希:

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

【讨论】:

    【解决方案3】:

    我认为 Ruby 不支持真正的枚举——尽管如此,仍有可用的解决方案。

    Enumerations and Ruby

    【讨论】:

      【解决方案4】:

      在 ruby​​ 中定义枚举以使用具有常量变量的类的最简单方法。

      class WindowState
        Open = 1
        Closed = 2
        Max = 3
        Min = 4
      end
      

      【讨论】:

        【解决方案5】:

        像其他人所说的那样创建一个类或散列会起作用。但是,Ruby 要做的是使用symbols。 Ruby 中的符号以冒号开头,如下所示:

        greetingtype = :hello
        

        它们有点像只包含名称的对象。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-02-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-04-03
          • 2010-09-09
          相关资源
          最近更新 更多