gpt4 book ai didi

scala - `toString`中的 `scala.Enumeration$Value`是如何实现的?

转载 作者:行者123 更新时间:2023-12-02 07:52:24 25 4
gpt4 key购买 nike

我有一个枚举 Fruit 定义为:

object Fruit extends Enumeration {
val Apple, Banana, Cherry = Value
}

现在打印这个枚举的值,在 Scala 2.7.x 上给出:

scala> Fruit foreach println
line1$object$$iw$$iw$Fruit(0)
line1$object$$iw$$iw$Fruit(1)
line1$object$$iw$$iw$Fruit(2)

但是在 Scala 2.8 上同样的操作给出:

scala> Fruit foreach println       
warning: there were deprecation warnings; re-run with -deprecation for details
Apple
Banana
Cherry

我的问题是:

Scala 2.8中Enumeration中的toString方法是如何实现的?我尝试查看 Enumeration 的源代码,但什么也看不懂。

最佳答案

实现基于 Java 反射 API。

如果您为枚举值定义 val:

object Fruit extends Enumeration {
val Apple, Banana, Cherry = Value
}

类Fruit中有val的方法:

scala> Fruit.getClass.getMethods filter (_.getName.contains("Apple")) foreach println

public scala.Enumeration$Value line10$object$$iw$$iw$Fruit$.Apple()

toString电话 Enumeration.this.nameOf(i)如果未明确设置名称。此方法将尝试查找返回 Value 的枚举类中的所有方法。实例。

val methods = getClass.getMethods
for (m <- methods
if (classOf[Value].isAssignableFrom(m.getReturnType) &&
!java.lang.reflect.Modifier.isFinal(m.getModifiers) &&
m.getParameterTypes.isEmpty &&
isValDef(m)))

这些是 Fruit 类的方法。

然后它使用方法的名称和枚举值的 id 来构建映射 id -> name并使用枚举值的 id 从 map 中检索名称。

val name = m.getName
// invoke method to obtain actual `Value` instance
val value = m.invoke(this)
// invoke `id` method
val idMeth = classOf[Val].getMethod("id")
val id: Int = idMeth.invoke(value).asInstanceOf[java.lang.Integer].intValue()

如果你像这样定义一个枚举,这个实现很容易被破坏:

object X extends Enumeration {
val Y = Value
}
object Fruit extends Enumeration {
val x = X.Y
val A,B,C = Value
}

这个 Fruit.value 返回 object$Fruit.ValueSet(x, B, C)不是object$Fruit.ValueSet(A, B, C) .

关于scala - `toString`中的 `scala.Enumeration$Value`是如何实现的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2918798/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com