如何向 Scala 枚举对象添加方法?

发布于 2024-08-15 07:15:19 字数 2184 浏览 7 评论 0原文

我正在使用 Scala 2.8 并定义这样的枚举:

object Stooges extends Enumeration {
  type Stooge = Value
  val Larry, Curly, Moe = Value
}

我想向此枚举添加一个循环到“下一个”傀儡的方法。我可以在 Stooges 之外定义这样一个方法,并且这在测试程序中工作得很好:

def nextStooge(v:Stooges.Stooge):Stooges.Stooge =
  Stooges((v.id+1) % Stooges.values.size)

我真正想要的是将此方法添加到 Stooges 中,并且我已经尝试做这样的事情(同时使用 Stooges.Stooge 和 Stooges.Value) 。这些都可以编译。但是运行这样的程序:

import Stooges._
object App extends Application {
  println(Stooges.nextStooge(Larry))
}

会产生:

Exception in thread "main" java.lang.ExceptionInInitializerError
        at demo.App.main(Stooges.scala)
Caused by: java.lang.IllegalArgumentException: wrong number of arguments
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:592)
        at scala.Enumeration$$anonfun$scala$Enumeration$$nameOf$2.apply(Enumeration.scala:176)
        at scala.Enumeration$$anonfun$scala$Enumeration$$nameOf$2.apply(Enumeration.scala:171)
        at scala.collection.TraversableLike$WithFilter$$anonfun$foreach$1.apply(TraversableLike.scala:1200)
        at scala.collection.IndexedSeqLike$class.foreach(IndexedSeqLike.scala:85)
        at scala.collection.mutable.ArrayOps.foreach(ArrayOps.scala:20)
        at scala.collection.TraversableLike$WithFilter.foreach(TraversableLike.scala:1199)
        at scala.Enumeration.scala$Enumeration$$nameOf(Enumeration.scala:171)
        at scala.Enumeration$Val.toString(Enumeration.scala:237)
        at java.lang.String.valueOf(String.java:2615)
        at java.io.PrintStream.print(PrintStream.java:616)
        at java.io.PrintStream.println(PrintStream.java:753)
        at scala.Console$.println(Console.scala:198)
        at scala.Predef$.println(Predef.scala:152)
        at demo.App$.<init>(Stooges.scala:14)
        at demo.App$.<clinit>(Stooges.scala)

这是一个错误还是一个坏主意?

I'm using Scala 2.8 and defining an Enumeration like this:

object Stooges extends Enumeration {
  type Stooge = Value
  val Larry, Curly, Moe = Value
}

And I want to add a method to this Enumeration that cycles to the "next" stooge. I can define such a method outside Stooges and this works in a test program just fine:

def nextStooge(v:Stooges.Stooge):Stooges.Stooge =
  Stooges((v.id+1) % Stooges.values.size)

What I'd really like is to add this method to Stooges and I have tried doing such a thing (using both Stooges.Stooge and Stooges.Value). Those both compile. But running a program like this:

import Stooges._
object App extends Application {
  println(Stooges.nextStooge(Larry))
}

yields:

Exception in thread "main" java.lang.ExceptionInInitializerError
        at demo.App.main(Stooges.scala)
Caused by: java.lang.IllegalArgumentException: wrong number of arguments
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:592)
        at scala.Enumeration$anonfun$scala$Enumeration$nameOf$2.apply(Enumeration.scala:176)
        at scala.Enumeration$anonfun$scala$Enumeration$nameOf$2.apply(Enumeration.scala:171)
        at scala.collection.TraversableLike$WithFilter$anonfun$foreach$1.apply(TraversableLike.scala:1200)
        at scala.collection.IndexedSeqLike$class.foreach(IndexedSeqLike.scala:85)
        at scala.collection.mutable.ArrayOps.foreach(ArrayOps.scala:20)
        at scala.collection.TraversableLike$WithFilter.foreach(TraversableLike.scala:1199)
        at scala.Enumeration.scala$Enumeration$nameOf(Enumeration.scala:171)
        at scala.Enumeration$Val.toString(Enumeration.scala:237)
        at java.lang.String.valueOf(String.java:2615)
        at java.io.PrintStream.print(PrintStream.java:616)
        at java.io.PrintStream.println(PrintStream.java:753)
        at scala.Console$.println(Console.scala:198)
        at scala.Predef$.println(Predef.scala:152)
        at demo.App$.<init>(Stooges.scala:14)
        at demo.App$.<clinit>(Stooges.scala)

Is this a bug or just a bad idea?

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

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

发布评论

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

评论(2

欢你一世 2024-08-22 07:15:19

这对我有用:

scala> object Stooges extends Enumeration {
     |   type Stooge = Value
     |   val Larry = Value("Larry")
     |   val Curly = Value("Curly")
     |   val Moe = Value("Moe")
     |
     |   def nextStooge(v:Stooges.Stooge) = Stooges((v.id+1) % Stooges.maxId)
     | }
defined module Stooges

scala>

scala> import Stooges._
import Stooges._

scala> nextStooge(Larry)
res0: Stooges.Value = Curly

scala> nextStooge(Curly)
res1: Stooges.Value = Moe

scala> nextStooge(Moe)
res2: Stooges.Value = Larry

能够说 Larry.nextStooge 而不是 nextStooge(Larry) 绝对会更好。我想你必须使用自定义密封类来实现它。

This works for me:

scala> object Stooges extends Enumeration {
     |   type Stooge = Value
     |   val Larry = Value("Larry")
     |   val Curly = Value("Curly")
     |   val Moe = Value("Moe")
     |
     |   def nextStooge(v:Stooges.Stooge) = Stooges((v.id+1) % Stooges.maxId)
     | }
defined module Stooges

scala>

scala> import Stooges._
import Stooges._

scala> nextStooge(Larry)
res0: Stooges.Value = Curly

scala> nextStooge(Curly)
res1: Stooges.Value = Moe

scala> nextStooge(Moe)
res2: Stooges.Value = Larry

It would be definetively nicer to be able to say Larry.nextStooge instead of nextStooge(Larry). I suppose you have to implement that with a custom sealed class.

假装爱人 2024-08-22 07:15:19

这是一个错误。这种初始化正在做一些非常奇怪的事情。我要开一张票(完成,#2827)不存在。

This is a bug. That initalization is doing something awfully strange. I'm going to open a ticket (done, #2827), if none exists.

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