Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
具有有限离散值的Ruby类_Ruby_Initialization - Fatal编程技术网

具有有限离散值的Ruby类

具有有限离散值的Ruby类,ruby,initialization,Ruby,Initialization,假设我计划编写一个赛马博彩应用程序,我想要一个racesresult类,它可以有四个离散值:Win、Place、Show和“null对象”类Lose 我是从C#背景来到Ruby的,我通常会使用enum,或者可能是一系列由私有构造函数创建的静态只读字段,如下所示: public class RaceResult { public static RaceResult Win = new RaceResult(1); // ... private int lowestPositionTo

假设我计划编写一个赛马博彩应用程序,我想要一个
racesresult
类,它可以有四个离散值:
Win
Place
Show
和“null对象”类
Lose

我是从C#背景来到Ruby的,我通常会使用
enum
,或者可能是一系列由私有构造函数创建的静态只读字段,如下所示:

public class RaceResult {
  public static RaceResult Win = new RaceResult(1);
  // ...

  private int lowestPositionToWin;

  private RaceResult(int position) {
    lowestPositionToWin = position;
  }

  private bool PaysOut(int placement) {
    return placement <= lowestPositionToWin; // logic may be flawed here
  }
}
公共类比赛结果{
公共静态比赛结果赢=新比赛结果(1);
// ...
下位托温私人酒店;
私人比赛结果(国际位置){
lowestPositionToWin=位置;
}
私人布尔佩苏特(内部配售){

return placement不确定我是否理解您的要求,但是一个更像红宝石的怎么样

race_results = { win: 1, place: 2, show: 3, lose: 4 }
根据,在搜索“Ruby equired of enum”时发现,您可以使用模块和常量构建类似enum的结构:

module RaceResult
    LOSE = 0
    WIN = 1
    PLACE = 2
    SHOW = 4
end

result = RaceResult::WIN
它的优点是能够对值使用位运算符(例如,
racesult::WIN&racesult::SHOW
),即使在这个特定的应用程序中可能不需要它

编辑:您甚至可以进一步为代码定义枚举创建函数:

def Enum(values)
    result = Module.new
    i = 0
    values.each do |name|
        result.const_set name, 2**i
        i += 1
    end
    return result.freeze
end

RaceResults = Enum ["LOSE", "WIN", "PLACE", "SHOW"]
*尽管使用这种最小的实现,LOSE并不是默认的零值/空对象

实际类C#枚举 正如您在编辑中提到的,您还需要一些行为(函数),因此您可能希望实际使用一个类有了so,我们仍然可以使用通常的按位运算符,就像普通枚举一样。在下面的代码段中,第一个类定义创建了一个通用的
Enum
类,该类应由任何实际枚举继承(这是枚举的实现)。第二个类是实际的枚举,在我们的例子中是
racesults
。请注意,它继承
enum
,并使用构造函数定义其常量(稍后将详细介绍)。它还定义了可以对其调用的方法,如示例所示

class Enum
    def initialize(n)
        @value = n
    end

    def method_missing(name, *args, &blk)
        ret = @value.send(name, *args, &blk)
        ret.is_a? Numeric ? Enum.new(ret) : ret
    end
end

class RaceResults < Enum
    LOSE = self.new 0
    WIN = self.new 1
    PLACE = self.new 2
    SHOW = self.new 4

    def doSomething
        puts "did something useful, and btw, numerically I am #{@value}"
    end
end

RaceResults::WIN.doSomething
类枚举
def初始化(n)
@值=n
结束
def方法_缺失(名称、*args和blk)
ret=@value.send(name,*args,&blk)
ret.u是数字枚举新(ret):ret
结束
结束
类结果<枚举
LOSE=self.new 0
WIN=self.new 1
地点=self.new 2
SHOW=self.new 4
def剂量测定法
放置“做了一些有用的事情,顺便说一句,数字上我是#{@value}”
结束
结束
比赛结果:赢
在最后一行中,您可以看到如何使用定义的方法,以及如何访问常量值


您可能会问,为什么要使用构造函数来定义可能的值?好吧,主要是为了仍然可以使用位运算符(
&
|
,等等),同时能够从相同的值调用任何实例方法。这比使用转换方法更透明,比实际实现运算符更懒惰。

哈希解决了我只有一个值的情况。我更新了我的问题,以显示可能还涉及到一些行为。这更接近我想要的t、 如何将这些常量分配给自定义对象?@neontapir查看第一个代码段,在这两种方法中,您只需使用
anyVariable=TheEnum::SOME_CONSTANT
。第二个代码段只是一种轻松生成这些“枚举”的方法。@neontapir我没有阅读您的编辑,抱歉,我将尝试展开this@neontapir完成后,请阅读“实际的C#-like enums”部分。很漂亮,谢谢@Kroltan花时间。我学到了很多。