为什么Array.fill采用隐式scala.reflect.ClassManifest?

为什么Array.fill采用隐式scala.reflect.ClassManifest?,scala,reflection,Scala,Reflection,所以我在玩用Scala编写播放器的游戏。在作战代码中,某些类是不允许的,如果您试图访问它们,则会出现运行时异常。当我使用该函数时,我从battlecode服务器收到一条消息,说[java]非法类:scala/reflect/Manifest$。这是一条令人不快的线: val g_score = Array.fill[Int](rc.getMapWidth(), rc.getMapHeight())(0) 该方法采用隐式ClassManifest参数,该参数包含以下文档: A ClassMani

所以我在玩用Scala编写播放器的游戏。在作战代码中,某些类是不允许的,如果您试图访问它们,则会出现运行时异常。当我使用该函数时,我从battlecode服务器收到一条消息,说
[java]非法类: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有真正的2D数组吗
Array.fill
似乎返回一个
数组[Array[T]]
,这是我找到的唯一编写自己的数组的方法。这似乎也不雅观


编辑:使用Scala 2.9.1了解背景信息,请参阅以下相关问题:。在这个答案中,您将找到为什么数组需要清单的解释

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

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

正如评论中所说,Scala 2.10中不推荐使用清单,并用
ClassTag
替换清单


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

public static class Helper {
    public static int[][] makeArray(int d1, int d2) { return new int[d1][d2](); }
}
(希望这是有效的java代码,有点生疏)


另外,您是否尝试使用
新数组[array[Int]](d1)
创建外部数组,然后迭代创建内部数组?

作为注释,Scala 2.10将其替换为
类标记。不确定这是否重要。战斗代码服务器有Scala 2.9,并且所有东西都兼容。问题是,根据作战代码规则集,不允许使用某些类的实例。检测到使用任何可能使您有机会利用游戏的类,并引发异常;他们说您应该同时包括scala-compiler.jar(出于任何原因?)和scala-library.jar;你这么做了吗?是的,我的问题(编辑)说错了。我安装的系统版本是2.9.2,但battlecode使用的版本是2.9.1。@AndrewMyers--你的意思是,除了你提供的类之外,你不能使用任何其他类?这对于Scala来说有点棘手。已经有一个case类将添加
产品
等等。不过,请看我的编辑。您可以使用标准库类,但有一个禁止使用的列表。这通常是涉及反思或在线编译的事情。任何允许你修改虚拟机状态的东西,以某种方式绕过游戏规则,或者获得比你想象的更多的关于游戏状态的信息。