1

所以我正在尝试用 Scala编写一个战斗代码播放器。在战斗代码中,某些类是不允许的,如果您尝试访问它们,则会出现运行时异常。当我使用Array.fill函数时,我从战斗代码服务器收到一条消息,说[java] Illegal class: scala/reflect/Manifest$. 这是违规行:

val g_score = Array.fill[Int](rc.getMapWidth(), rc.getMapHeight())(0)

ClassManifest该方法采用具有以下文档的隐式参数:

A ClassManifest[T] is an opaque descriptor for type T. It is used by the compiler
to preserve information necessary for instantiating Arrays in those cases where
the element type is unknown at compile time.

但我在编译时确实知道数组元素的类型,如上所示,我明确声明它们将是Int. 有没有办法避免这种情况?要解决方法,我编写了自己的Array.fill. 这似乎是一个黑客。顺便说一句,Scala 有真正的二维数组吗? Array.fill似乎返回一个Array[Array[T]]这是我发现自己写的唯一方法。这似乎也不优雅。

编辑:使用 Scala 2.9.1

4

1 回答 1

3

有关背景信息,请参阅此相关问题:什么是 Scala 中的清单以及何时需要它?. 在这个答案中,您将找到一个解释,为什么数组需要清单。

简而言之:尽管 JVM 使用类型擦除,但数组是一个例外,需要一个清单。由于您可以编译代码,因此找到了该清单(清单始终可用于正确的类型)。您的错误发生在运行时。

我不知道 Battlecode 服务器的详细信息,但有两种可能性:要么您正在使用二进制不兼容的 Scala 版本运行编译的类(主要版本不同,例如使用 Scala 2.9 编译,而服务器使用 2.10)。或者服务器在其类路径中甚至没有scala-library.jar 。

正如评论中所说,清单在 Scala 2.10 中已弃用,并由ClassTag.


编辑:所以似乎类加载器人为地限制了允许的类。我的建议是:添加一个辅助 Java 类。您可以轻松混合 Java 和 Scala 代码。如果只是关于Int-Array实例化,您可以提供如下内容:

public static class Helper {
    public static int[][] makeArray(int d1, int d2) { return new int[d1][d2](); }
}

(希望这是有效的java代码,有点生疏)

另外,您是否尝试过使用 来创建外部数组new Array[Array[Int]](d1),然后迭代以创建内部数组?

于 2013-01-16T19:58:09.637 回答