如何通过将特征与反射混合来访问对象内的对象?

发布于 2024-10-03 11:06:04 字数 1041 浏览 3 评论 0原文

如何通过反射获取对象内的所有对象?

考虑这段代码:

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)

trait MyEnum {
  val values: List[MonthDay] = this.getClass.getField("MODULE$")...
  val next: MonthDay = ...
  val previous: MonthDay = ...
}

//Of course the user can create his own 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: MonthDaydef previous: MonthDay不重复自己几次(这绝对是至关重要的!)。

这个想法是,values 访问 MonthDay 对象,并通过反射查找它们正在扩展的类 (MonthDay) 的所有单例对象。

How can I get all of the objects within an object with reflection?

Consider this code:

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)

trait MyEnum {
  val values: List[MonthDay] = this.getClass.getField("MODULE$")...
  val next: MonthDay = ...
  val previous: MonthDay = ...
}

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

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

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) without repeating myself a few times (this is absolutely crucial!).

The idea is that values accesses the MonthDay object and finds all singleton objects of the class they are extending (MonthDay) with reflection.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

终难愈 2024-10-10 11:06:04

我的解决方案基于 Landei 的答案 是:

trait MyEnum{
   def valsOfType[T:Manifest] = {
      val c=implicitly[Manifest[T]].erasure
      for {m <- getClass.getMethods 
           if m.getParameterTypes.isEmpty && c.isAssignableFrom(m.getReturnType)
      } yield (m.invoke(this).asInstanceOf[T])
   }
}

class MonthDay(month:Int,day:Int)

object MonthDay extends MyEnum {
   //maybe you want to call this "holidays" instead
   lazy val values = valsOfType[MonthDay] 

   val NewYear       = new MonthDay( 1,  1)
   val UnityDay      = new MonthDay(11,  9)
   val SaintNicholas = new MonthDay(12,  6)
   val Christmas     = new MonthDay(12, 24)
}

我认为您不应该再调用此 MyEnum,因为枚举类型意味着一组封闭的值。

(如果枚举值定义为对象,则不起作用)

My solution, based on Landei's answer would be:

trait MyEnum{
   def valsOfType[T:Manifest] = {
      val c=implicitly[Manifest[T]].erasure
      for {m <- getClass.getMethods 
           if m.getParameterTypes.isEmpty && c.isAssignableFrom(m.getReturnType)
      } yield (m.invoke(this).asInstanceOf[T])
   }
}

class MonthDay(month:Int,day:Int)

object MonthDay extends MyEnum {
   //maybe you want to call this "holidays" instead
   lazy val values = valsOfType[MonthDay] 

   val NewYear       = new MonthDay( 1,  1)
   val UnityDay      = new MonthDay(11,  9)
   val SaintNicholas = new MonthDay(12,  6)
   val Christmas     = new MonthDay(12, 24)
}

I don't think you should call this MyEnum anymore, because an enumerated type implies a closed set of values.

(Doesn't work if the enumeration values are defined as objects)

夏有森光若流苏 2024-10-10 11:06:04

您应该能够使用预先存在的 Scala Enumeration 类:http://www.scala-lang.org/api/current/scala/Enumeration.html

它似乎非常接近您的用例!

You should be able to use the pre-existing Scala Enumeration class: http://www.scala-lang.org/api/current/scala/Enumeration.html

It seems to come very close to your use-case!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文