Scala枚举与Singleton对象作为枚举元素和迭代的可能性? [英] Scala enumerations with Singleton objects as enumeration elements and a possibility to iterate over them?

查看:160
本文介绍了Scala枚举与Singleton对象作为枚举元素和迭代的可能性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经查看了 Scala问题关于模拟Java的枚举 案例类与枚举,但似乎太多的努力太少的好处。

I already looked at the Scala question about emulating Java's enum and case classes vs. Enumeration but It seems too much effort for too less benefit.

基本上我想要一个方法返回所有单例对象 DayOfWeek 而不重复自己几次。

Basically I would like to have a values method returning all singleton objects of DayOfWeek without repeating myself a few times.

这是我的代码如何:

object DayOfWeek extends MyEnum {
  object MONDAY extends DayOfWeek(1)
  object TUESDAY extends DayOfWeek(2)
  object WEDNESDAY extends DayOfWeek(3)
  object THURSDAY extends DayOfWeek(4)
  object FRIDAY extends DayOfWeek(5)
  object SATURDAY extends DayOfWeek(6)
  object SUNDAY extends DayOfWeek(7)
}

class DayOfWeek(ordinal: Int)

方法应该返回像这样写的东西:

The method values should return something like if it had been written like this:

val values = Array(MONDAY, TUESDAY, WEDNESDAY, THURSDAY,
                   FRIDAY, SATURDAY, SUNDAY)

一切都应该在 MyEnum trait,所以我只需要扩展它来获取功能。

Everything should happen in the MyEnum trait so I only need to extend it to get the functionality.

trait MyEnum {
  val values = this.getClass.getField("MODULE$") etc. etc.
}


$ b $任何建议如何完成这一点?
这个想法是访问类,并找到他们正在扩展的类的所有单例对象。

Any suggestion how this could be done exactly? The idea is that values accesses the class and finds all singleton objects of the class they are extending.

编辑:看起来所有的建议都没有考虑到用户可以创建对象,这当然应该与定义的对象相比。

我将尝试另一个例子,也许更清楚:

I'll try to give another example, maybe it is more clear:

object MonthDay extends MyEnum {
  //Some important holidays
  object NewYear       extends MonthDay( 1,  1)
  object UnityDay      extends MonthDay(11,  9)
  object SaintNicholas extends MonthDay(12,  6)
  object Christmas     extends MonthDay(12, 24)
}

class MonthDay(month: Int, day: Int)

//Of course the user can create other MonthDays
val myBirthDay = new MonthDay(month, day)

if(!MonthDay.values.contains(myBirthDay)) "Well, I probably have to work"
else "Great, it is a holiday!"

我想拥有一个特质( MyEnum )我可以混合到持有我的枚举对象的对象的方法返回一个列表( def values:List [MonthDay] )或迭代他们( def next:MonthDay def previous:MonthDay )。

I want to have a trait (MyEnum) which I can mix into the object holding my "enumeration objects" with methods to return a list of them (def values: List[MonthDay]) or iterate over them (def next: MonthDay or def previous: MonthDay).

>我根据Ken Bloom的要求为这个问题的第二部分创建了一个新问题。

PPS: I created a new question for the second part of this question as requested by Ken Bloom.

推荐答案

这个怎么样?它要求您为每个新值实际调用 add 方法,但返回正确的类型。

How about this? It requires you to actually call an add method for each new value, but values returns the right type.

abstract class MyEnum{

   type Value     //define me to be the value type for this MyEnum

   private var _values:List[Value] = Nil
   def values = _values    
   protected def add(newValue:Value) = {
      _values = newValue::_values
      newValue
   }
}

object DayOfWeek extends MyEnum{
   class Value(val dayNum:Int)
   val SUNDAY    = add(new Value(1))
   val MONDAY    = add(new Value(2))
   val TUESDAY   = add(new Value(3))
   val WEDNESDAY = add(new Value(4))
   val THURSDAY  = add(new Value(5))
   val FRIDAY    = add(new Value(6))
   val SATURDAY  = add(new Value(7))
}

现在可以调用

println(DayOfWeek.values map (_.dayNum))

如果您需要对不同对象有不同方法定义的单例对象,您可以像这样创建匿名类:

If you need singleton objects that have different definitions of the methods on different objects, you can create anonymous classes like so:

add(new Value{
      override def dayNum=8
    })

这篇关于Scala枚举与Singleton对象作为枚举元素和迭代的可能性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆