scala квазиквоты строковая переменная поднимается в несколько шагов
Это то, что я хочу:
scala> var x:Int = 10
x: Int = 10
scala> var y:Int = 20
y: Int = 20
scala> val ret = q"return $x>$y"
ret: universe.Return = return 10.$greater(20)
scala> val result1 = toolbox.compile(ret)()
result1: Any = false
Но проблема в том, что я получу выражение $ x> $ y в строке var, например
scala> m
res20: String = $x>$y
И тогда я хочу выполнить операцию как,
var ret = q"return $m"
но это возвращение
scala> var ret = q"return $m"
ret: universe.Return = return "$x>$y"
который не служит цели. Как я могу получить значения x и y на последнем шаге вместо $ x и $y.
1 ответ
Вы можете смешать квазицитаты и ToolBox.parse
для достижения результатов в основном то, что вы ищете:
import scala.tools.reflect.ToolBox
import scala.reflect.runtime.universe._
val toolbox = scala.reflect.runtime.currentMirror.mkToolBox()
val s = "10>20"
val ret = q"return ${toolbox.parse(s)}"
// reflect.runtime.universe.Return = return 10.$greater(20)
toolbox.eval(ret)
// Any = false
Использование ваших значений в качестве переменных:
import scala.tools.reflect.ToolBox
import scala.reflect.runtime.universe._
val toolbox = scala.reflect.runtime.currentMirror.mkToolBox()
val x = 10
val y = 20
val m = "x>y"
val ret = q"return ${toolbox.parse(m)}"
// reflect.runtime.universe.Return = return x.$greater(y)
Если вы оцениваете q"return ${toolbox.parse(m)}"
вы увидите ошибку, потому что x
а также y
не в объеме.
scala> toolbox.eval(q"return ${toolbox.parse(m)}")
scala.tools.reflect.ToolBoxError: reflective compilation has failed:
object > is not a member of package x ...
Чтобы это исправить:
import scala.tools.reflect.ToolBox
import scala.reflect.runtime.universe._
val toolbox = scala.reflect.runtime.currentMirror.mkToolBox()
val q1 = q"val x = 10; val y = 20; "
val m = "x>y"
val ret = q"""
| ..$q1
| return ${toolbox.parse(m)}
| """
toolbox.eval(ret)
// Any = false