[scala.Enumerator.nextName
和scala.Enumerator.nextName
当前读取:
.nextNameOrNull
随后调用/** The string to use to name the next created value. */
protected var nextName: Iterator[String] = _
private def nextNameOrNull =
if (nextName != null && nextName.hasNext) nextName.next() else null
以获取用于枚举中创建的项目的名称。
此代码实际上是如何实现的?
当我将其复制粘贴到一个简单的示例中:
nextNameOrNull
它打印:class MyBaseClass extends Serializable {
/** The string to use to name the next created value. */
protected var nextName: Iterator[String] = _
private def nextNameOrNull =
if (nextName != null && nextName.hasNext) nextName.next() else null
protected final def Value(): Val = Val(nextNameOrNull)
case class Val(name:String)
}
object MyObject extends MyBaseClass {
val myValue = Value
println("Hello from MyObject, myValue: " + myValue)
}
,而不是希望的Hello from MyObject, myValue: Val(null)
我需要添加什么才能使其正常工作?
在Scala JVM中,如果Val(myValue)
返回null,则获取Enumeration
uses reflection以获取分配给Value
的val的名称。
在Scala.js中,我们没有这种奢侈感(没有反射支持)。因此,Scala.js编译器特殊情况 nextNameOrNull
,以便使用它的代码可以工作。
[如果要实现一些知道分配给它的scala.Enumeration
名称的方法,请查看sbt的val
。从2.10开始,Scala的Enumerations可能已经实现了,但是更老了。
project
macro甚至对于原始Scala也不再起作用-因为不推荐使用并删除将名称序列传递给构造函数的方法。这是使用原始scala的project
(不是scala-js中替换的代码)对2.11.2的执行:
nextNameOrNull
在Enumeration
中的Enumeration
中,在构造函数之一内部用于显式指定名称(在scala> object MyObject extends Enumeration {
| val MyValue1, MyValue2 = Value
|
| println("nextName: " + nextName)
| }
defined object MyObject
scala> MyObject
nextName: null //still null
中删除):
2.10.x
现在此构造函数已删除,nextName
只是无效代码。 Scala使用2.11.x
为@deprecated("Names should be specified individually or discovered via reflection", "2.10.0")
def this(initial: Int, names: String*) = {
this(initial)
this.nextName = names.iterator
}
}
提供名称(如果未指定它们:
nextName
因此,它默认使用反射。您可以按照populateNameMap()
的描述为每个值明确指定名称。
我认为与ScalaJs相同,不同之处在于它没有nameOf
方法,因为JavaScript没有这种反射-因此,非明确命名参数的结果是:
private def populateNameMap() {
val fields = getClass.getDeclaredFields
def isValDef(m: JMethod) = fields exists (fd => fd.getName == m.getName && fd.getType == m.getReturnType)
// The list of possible Value methods: 0-args which return a conforming type
val methods = getClass.getMethods filter (m => m.getParameterTypes.isEmpty &&
classOf[Value].isAssignableFrom(m.getReturnType) &&
m.getDeclaringClass != classOf[Enumeration] &&
isValDef(m))
methods foreach { m =>
val name = m.getName
// invoke method to obtain actual `Value` instance
val value = m.invoke(this).asInstanceOf[Value]
// verify that outer points to the correct Enumeration: ticket #3616.
if (value.outerEnum eq thisenum) {
val id = Int.unbox(classOf[Val] getMethod "id" invoke value)
nmap += ((id, name))
}
}
}
但是同样,here在Scala和Scala-Js中都死了-它总是返回null。