7

我有一个简单的应用程序:

object Test extends App {
  implicit def t2mapper[X, X0 <: X, X1 <: X](t: (X0, X1)) = new {
    def map[R](f: X => R) = (f(t._1), f(t._2))
  }
  println("Hello!")
  val (foo, bar) = (1, 2) map (_ * 2)
  println((foo, bar))
}

t2mapper来自这个答案。)

代码编译得很好:

$ scalac -version
Scala compiler version 2.9.1 -- Copyright 2002-2011, LAMP/EPFL
$ scalac -unchecked Test.scala
$ 

但是在运行时,它会抛出一个IllegalAccessError(在打印之前): Hello!

$ java -版本
java版本“1.6.0_24”
OpenJDK 运行时环境 (IcedTea6 1.11.1) (6b24-1.11.1-4ubuntu3)
OpenJDK Server VM(build 20.0-b12,混合模式)
$ 斯卡拉测试
java.lang.IllegalAccessError:试图从类 Test$delayedInit$body 访问字段 Test$.reflParams$Cache1
        在 Test$delayedInit$body.(Test.scala:6)
        在 Test$.(Test.scala:1)
        在 Test$.(Test.scala)
        在 Test.main(Test.scala)
        在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
        在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        在 java.lang.reflect.Method.invoke(Method.java:616)
        在 scala.tools.nsc.util.ScalaClassLoader$$anonfun$run$1.apply(ScalaClassLoader.scala:78)
        在 scala.tools.nsc.util.ScalaClassLoader$class.asContext(ScalaClassLoader.scala:24)
        在 scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.asContext(ScalaClassLoader.scala:88)
        在 scala.tools.nsc.util.ScalaClassLoader$class.run(ScalaClassLoader.scala:78)
        在 scala.tools.nsc.util.ScalaClassLoader$URLClassLoader.run(ScalaClassLoader.scala:101)
        在 scala.tools.nsc.ObjectRunner$.run(ObjectRunner.scala:33)
        在 scala.tools.nsc.ObjectRunner$.runAndCatch(ObjectRunner.scala:40)
        在 scala.tools.nsc.MainGenericRunner.runTarget$1(MainGenericRunner.scala:56)
        在 scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:80)
        在 scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:89)
        在 scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)

请注意,最后两行替换为

  println((1, 2) map (_ * 2))

或者

  val (foo, bar) = (2, 4)
  println((foo, bar))

或者

  val intermediate = (1, 2) map (_ * 2)
  val (foo, bar) = intermediate
  println((foo, bar))

(2,4)它按预期打印。但是当包裹在一个块中时

  {
    val intermediate = (1, 2) map (_ * 2)
    val (foo, bar) = intermediate
    println((foo, bar))
  }

或者

  private val blah = {
    val intermediate = (1, 2) map (_ * 2)
    val (foo, bar) = intermediate
    println((foo, bar))
  }

它抛出异常。

为什么第一种和最后一种方法会导致 JVM 在运行时抛出错误?

4

1 回答 1

5

看起来有一些相关的开放错误。例如,这可能是相关的:

https://issues.scala-lang.org/browse/SI-5251?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel

请注意,您也可以创建一个main方法而不是扩展App,它会起作用。

编辑:

当您使用此行时(我扩展了隐式):

val (foo, bar) = t2mapper((1, 2)) map (_ * 2)

然后将鼠标悬停foobar在 Eclipse 中显示private[this] val foo.

因此,它似乎与 SI-5251 非常相似。

于 2012-07-02T23:32:42.490 回答