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には実際の2Dアレイがありますか? 私が自分で書くために見つけた唯一の方法であるArray.fillを返すようです。Array[Array[T]]これもエレガントではないようです。

編集:Scala2.9.1の使用

4

1 に答える 1

3

背景情報については、この関連する質問を参照してください:Scalaのマニフェストとは何ですか?いつ必要ですか?。この回答では、配列にマニフェストが必要な理由について説明しています。

つまり、JVMは型消去を使用しますが、配列は例外であり、マニフェストが必要です。コードをコンパイルできたので、そのマニフェストが見つかりました(マニフェストは常に適切なタイプで使用できます)。エラーは実行時に発生します。

バトルコードサーバーの詳細はわかりませんが、2つの可能性があります。コンパイルされたクラスをバイナリ互換バージョンの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 に答える