6

scalapいくつかのケース クラスのフィールド名を読み上げるために使用しています (この質問で説明されているように)。ケースクラスとそれらを分析するために使用するコードの両方scalapがコンパイルされ、クラスパス上の jar ファイルに配置されています。

今、このコードを使用するスクリプトを実行したいので、指示に従って次のようなものを思いつきました

::#!
@echo off
call scala -classpath *;./libs/* %0 %*
goto :eof
::!#
//Code relying on pre-compiled code that uses scalap

これは機能しません:

java.lang.ClassCastException: scala.None$ は scala.tools.nsc.interpreter.ByteCode$.caseParamNamesForPath(ByteCode. scala:45) で scala.Option にキャストできません。scala.tools.nsc.interpreter.ProductCompletion.caseNames( ProductCompletion.scala:22)

ただし、すべてをコンパイルすると、コードは正常に機能します。のような追加scalaのオプションを試してみ-savecompiledましたが、これは役に立ちませんでした。これはバグですか、それとも原則として機能しませんか? (もしそうなら、誰かが理由を説明できますか?私が言ったように、分析されるケースクラスscalapはコンパイルされます。)

注: Scala 2.9.1-1 を使用しています。

編集

これが私が本質的にやろうとしていることです(ケースクラスの複数のインスタンスを作成する簡単な方法を提供します):

//This is pre-compiled:
import scala.tools.nsc.interpreter.ProductCompletion
//...
trait MyFactoryTrait[T <: MyFactoryTrait[T] with Product] {
  this: T =>

  private[this] val copyMethod = this.getClass.getMethods.find(x => x.getName == "copy").get

  lazy val productCompletion = new ProductCompletion(this)

  /** The names of all specified fields. */
  lazy val fieldNames = productCompletion.caseNames //<- provokes the exception (see above)

  def createSeq(...):Seq[T] = {
    val x = fieldNames map { ... } // <- this method uses the fieldNames value
    //[...] invoke copyMethod to create instances
  }   
 // ...
}

//This is pre-compiled too: 
case class MyCaseClass(x: Int = 0, y: Int = 0) extends MyFactoryTrait[MyCaseClass]

//This should be interpreted (but crashes):
val seq = MyCaseClass().createSeq(...)

注: Scala 2.9.2 に移行しましたが、エラーは同じままです (おそらくバグではありません)。

4

1 に答える 1

0

これはコンパイラのバグです:

  • Intellij IDEA などの IDE 内でプログラムを実行すると、コードは正常に実行されますが、フィールド名が見つかりません。
  • scala を使用してコマンド ラインから実行すると、前述のエラーが発生します。

タイプ セーフでコンパイラを実行してランタイム ClassCastException をスローする方法はありません。

https://issues.scala-lang.org/secure/Dashboard.jspaでバグを開いてください

于 2012-07-09T08:31:09.003 に答える