Bevor wir diese Frage beantworten, müssen wir zuerst die Scala-Version reparieren und Ihre Frage reproduzierbar machen. Nehmen wir an, wir verwenden Scala 2.11.8, sbt 0.13.11 und spire-math 0.11.0.
Dann wird die blanke build.sbt könnte die aussehen wie folgt:
name := "test"
version := "1.0"
scalaVersion := "2.11.8"
libraryDependencies += "org.scala-lang" % "scala-compiler" % scalaVersion.value
libraryDependencies += "org.spire-math" %% "spire" % "0.11.0"
und der Code kann in Test.scala
Datei gespeichert werden, die aussehen wie:
import spire.implicits._
import scala.reflect.runtime.currentMirror
import scala.tools.reflect.ToolBox
object Test {
def main(args: Array[String]) = {
val toolBox = currentMirror.mkToolBox()
val src ="""
|(a: spire.math.Jet[Double],b: spire.math.Jet[Double]) => a + b
""".stripMargin
println (toolBox.eval(toolBox.parse(src)))
}
}
Nach sbt run
Ausführung, erhalten Sie:
$ sbt run
[info] Running Test
[error] scala.tools.reflect.ToolBoxError: reflective compilation has failed:
[error] could not find implicit value for parameter f: spire.algebra.Field[Double]
So ist Ihre Frage, warum tut t sein Fehlschlag, obwohl die in import spire.implicits._
definierten Implikationen in dem Bereich enthalten sind, in dem toolBox
instanziiert ist und eval
aufgerufen wird.
Nun, beachten Sie, dass Sie in Ihrem Anwendungsfall zwei Stufen haben, in denen der Compiler unabhängig aufgerufen wird. Die erste Stufe ist die Kompilation Test.scala
und die zweite Stufe ist die Kompilierung und Ausführung von (a: spire.math.Jet[Double],b: spire.math.Jet[Double]) => a + b
Diese zwei Stufen arbeiten nicht in der gleichen Laufzeit. In der ersten Phase wird der Compiler aufgerufen, um die Datei Test.scala
zu kompilieren, und in der zweiten wird er innerhalb der JVM-Laufzeit aufgerufen, um die Zeichenfolge src
zu kompilieren. Daher haben diese beiden Stufen nicht den gleichen Umfang, weil sie in unterschiedlichen Laufzeiten ausgeführt werden.
Eine schnelle Lösung für dieses Problem ist die "Wiedereinführung" der Implikationen im Rahmen der zweiten Stufe. Mit anderen Worten prepend Sie import spire.implicits._
in der Zeichenfolge, die Sie versuchen, zu kompilieren:
import spire.implicits._
import scala.reflect.runtime.currentMirror
import scala.tools.reflect.ToolBox
object Test {
def main(args: Array[String]) = {
val toolBox = currentMirror.mkToolBox()
val src ="""
|import spire.implicits._
|(a: spire.math.Jet[Double],b: spire.math.Jet[Double]) => a + b
""".stripMargin
println (toolBox.eval(toolBox.parse(src)))
}
}
, die zu den Ergebnissen:
$ sbt run
[info] Running Test
<function2>
[success] Total time: 5 s, completed Jul 13, 2016 1:48:59 AM
Hoffnung dies Ihre Frage beantwortet. Wenn Sie eine gründliche Antwort darauf möchten, wie der Scala-Compiler nach Implikationen in den Bereichen sucht, wäre ein guter Start here.
Was ist das Ziel? – cchantep
@cchanstep - Bearbeitet, um zu klären. – NietzscheanAI