Scala:无法将FOO转换为FOO

4
在Scala中,我对这个相当自指的错误消息感到非常困惑:
java.lang.ClassCastException: FOO cannot be cast to FOO

我希望能够将某人始终转换为其自身类型。

语境

我正在尝试运行包装在Scala编译器周围的以下代码,位于http://code.google.com/p/rooscaloo/source/browse/trunk/rooscaloo/src/org/darevay/rooscaloo/Interpreter.scala。不幸的是,当我执行以下操作时,Scala会说ResultHolder不能转换为ResultHolder

import org.darevay.rooscaloo._
println(new Interpreter().eval("2"))

我认为println应该接受Any。 实际上,Interpreter.eval返回一个ResultHolder类型,因此ResultHolder.value应该等于2
另外,尝试打印.value时会出错:
(fragment of Test.scala):3: error: value value is not a member of Any                                                                                                                                                 
println(new Interpreter().eval("2").value)

更多细节
java.lang.reflect.InvocationTargetException                                                                                                                                                                           
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        ...
Caused by: java.lang.ClassCastException: org.darevay.rooscaloo.ResultHolder cannot be cast to org.darevay.rooscaloo.ResultHolder
        at binder0$.set(<script>:1)
        at binder0.set(<script>)
        ... 24 more (unsure how to print them)

尽管我是一个Scala新手,但也许scala.tools.nsc.interpreter包的内部机制binder正在尝试做一些奇怪的事情。我正在使用scala Test.scala命令调用脚本。
问题:这个错误消息的原因是什么,真正的问题是什么,如何获取scala.tools.nsc.[interpreter]的可工作示例代码?谢谢。

8
当某人使用不同的类加载器加载相同的类时,通常会出现这种消息。这并非完全解决方案,但你可能需要进一步调查此问题。 - Sanjay T. Sharma
@Sanjay:谢谢。不幸的是,我对Java的内部工作原理并不太熟悉;那是什么意思?我知道.class文件是文件的编译版本,包含JVM字节码,并且ClassLoader是根据某些策略加载类的东西(我猜测有一种基于默认文件系统类路径的ClassLoader?)。然而,我对你的评论感到困惑,因为我不明白一个ClassLoader“存在”的地方,以及通常会导致多个ClassLoader在同一个程序中隐式使用的原因。谢谢。 - ninjagecko
Scala的“解释器”首先编译代码,然后将类加载到JVM中。 - Daniel C. Sobral
此外,这段代码似乎相当老旧。我尝试在Scala 2.7.7、2.8.1和trunk上运行它,但都出现了各种错误,都与org.darevay不在类路径中有关。我根本没有遇到你的错误,所以如果你能提供更多细节来重现(Scala版本,采取了哪些步骤),那将会很有帮助。 - Daniel C. Sobral
1个回答

0

我遇到了类似的问题,我已经将我的代码转换为使用Scala 2.9中引入的{{link1:IMain#mostRecentVar}}。这是我编写的{{link2:CompilerMatcher}}的代码:

  val main = new IMain(s)
  main.compileSources(files.map(toSourceFile(_)): _*)
  code map { c => main.interpret(c) match {
    case IR.Error => error("Error interpreting %s" format (c))
    case _ => 
  }}
  val recent = main.mostRecentVar
  val holder = main.valueOfTerm(recent)
  if (holder != Some(expected))
    println("actual: " + holder.map(_.toString).getOrElse{"None"})

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接