如何在 Scala 中处理枚举和路径依赖类型

发布于 2024-10-15 06:12:37 字数 330 浏览 3 评论 0原文

我遇到一个问题,其解决方案应该与此问题的解决方案等效:假设我想编写一个方法,给定一个枚举,返回其所有值的列表。我想写:

def makeList[E <: Enumeration](enum: E): List[enum.Value] = enum.values.toList

但是编译失败并出现非法依赖方法类型错误。改为这样写可以吗?

def makeList[E <: Enumeration](enum: E): List[E#Value] = enum.values.toList

I'm having a problem whose solution should be equivalent to the solution to this: Suppose I want to write a method which, given an Enumeration, returns a list of all its values. I want to write:

def makeList[E <: Enumeration](enum: E): List[enum.Value] = enum.values.toList

but compilation fails with an illegal dependent method type error. Is it OK to write this instead?

def makeList[E <: Enumeration](enum: E): List[E#Value] = enum.values.toList

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

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

发布评论

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

评论(2

酒浓于脸红 2024-10-22 06:12:37

您可以在那里使用路径相关类型,但它现在是一个实验性功能。对 scala 或 scalac 使用 -Xexperimental。

$ scala -Xexperimental
Welcome to Scala version 2.8.1.final (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_21).
Type in expressions to have them evaluated.
Type :help for more information.

scala> def makeList[E <: Enumeration](enum: E): List[enum.Value] = enum.values.toList
makeList: [E <: Enumeration](enum: E)List[enum.Value]

scala> object Bool extends Enumeration { 
     |   type Bool = Value
     |   val True, False = Value 
     | }
defined module Bool

scala> makeList(Bool)
res0: List[Bool.Value] = List(True, False)

You can use a path dependent type there but it's an experimental feature right now. Use -Xexperimental for scala or scalac.

$ scala -Xexperimental
Welcome to Scala version 2.8.1.final (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_21).
Type in expressions to have them evaluated.
Type :help for more information.

scala> def makeList[E <: Enumeration](enum: E): List[enum.Value] = enum.values.toList
makeList: [E <: Enumeration](enum: E)List[enum.Value]

scala> object Bool extends Enumeration { 
     |   type Bool = Value
     |   val True, False = Value 
     | }
defined module Bool

scala> makeList(Bool)
res0: List[Bool.Value] = List(True, False)
じ违心 2024-10-22 06:12:37

对我来说似乎没问题:

object WeekDay extends Enumeration { 
  type WeekDay = Value 
  val Mon, Tue, Wed, Thu, Fri, Sat, Sun = Value 
}

> makeList(WeekDay)
res2: List[WeekDay#Value] = List(Mon, Tue, Wed, Thu, Fri, Sat, Sun)

> makeList(WeekDay.Mon)
error: inferred type arguments [WeekDay.Value] do not conform to method makeList's type parameter bounds [E <: Enumeration]
       makeList(WeekDay.Mon)
       ^

更新回复评论:

我猜有人可以重写Value嵌套类而不是Val(我只是查看了来源,它没有被密封),但我想不出理由。请注意,通常,对于所有枚举,Value 都是相同的类型:

object Bool extends Enumeration { 
  type Bool = Value
  val True, False = Value 
}

> Bool.True.getClass
res8: java.lang.Class[_] = class scala.Enumeration$Val
> Bool.True.getClass == WeekDay.Mon.getClass
res7: Boolean = true

It seems to be OK to me:

object WeekDay extends Enumeration { 
  type WeekDay = Value 
  val Mon, Tue, Wed, Thu, Fri, Sat, Sun = Value 
}

> makeList(WeekDay)
res2: List[WeekDay#Value] = List(Mon, Tue, Wed, Thu, Fri, Sat, Sun)

> makeList(WeekDay.Mon)
error: inferred type arguments [WeekDay.Value] do not conform to method makeList's type parameter bounds [E <: Enumeration]
       makeList(WeekDay.Mon)
       ^

UPDATE in reply to the comment:

I guess someone could override the Value nested class instead of Val (I just looked at the source and it isn't sealed), but I can't think of a reason to. Note that normally, for all enumerations, Value is the same type:

object Bool extends Enumeration { 
  type Bool = Value
  val True, False = Value 
}

> Bool.True.getClass
res8: java.lang.Class[_] = class scala.Enumeration$Val
> Bool.True.getClass == WeekDay.Mon.getClass
res7: Boolean = true
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文