gpt4 book ai didi

scala - 如何在运行时编译/评估 Scala 表达式?

转载 作者:行者123 更新时间:2023-12-04 12:18:24 28 4
gpt4 key购买 nike

Scala 新手,正在寻找指向惯用解决方案的指针(如果有)。

我希望将用户提供的任意 Scala 函数(允许引用我在代码中定义的函数/类)应用于某些数据。

例如:我有 foo(s: String): Stringbar(s: String): String在我的 myprog.scala 中定义的函数.用户像这样运行我的程序:

$ scala myprog data.txt --func='(s: Str) => foo(bar(s)).reverse'

这将逐行运行数据文件,并发出将用户指定的函数应用于该行的结果。

为了加分,我可以确保用户定义的函数中没有副作用吗?如果不是,我是否可以限制该功能仅使用受限制的功能子集(我可以保证安全)?

最佳答案

@kenjiyoshida 有一个不错的 gist这显示了如何评估 Scala 代码。注意使用 Eval 时根据该要点,当 Scala 默认推断 Nothing 时,不指定返回值将导致运行时失败。 .

scala> Eval("println(\"Hello\")")
Hello
java.lang.ClassCastException: scala.runtime.BoxedUnit cannot be cast to scala.runtime.Nothing$
... 42 elided

对比
scala> Eval[Unit]("println(\"Hello\")")
Hello

它也可以很好地处理范围内的任何内容。
 object Thing {
val thing: Int = 5
}

object Eval {

def apply[A](string: String): A = {
val toolbox = currentMirror.mkToolBox()
val tree = toolbox.parse(string)
toolbox.eval(tree).asInstanceOf[A]
}

def fromFile[A](file: File): A =
apply(scala.io.Source.fromFile(file).mkString(""))

def fromFileName[A](file: String): A =
fromFile(new File(file))

}

object Thing2 {
val thing2 = Eval[Int]("Thing.thing") // 5
}

推特的 util 包以前有 util-eval ,但现在似乎已被弃用(并且在编译时也会触发编译器错误)。

至于你问题的第二部分,答案似乎是否定的。即使您禁用默认 Predef并导入自己,用户始终可以使用完全限定的包名称访问这些功能。您也许可以使用 Scala 的 scala.tools.reflect.ToolBox在传递给 eval 之前,首先解析您的字符串,然后与白名单进行比较,但那时事情可能会变得非常棘手,因为您将手动编写代码来清理 Scala AST(或至少拒绝危险输入)。这绝对不是一个“惯用的解决方案”。

关于scala - 如何在运行时编译/评估 Scala 表达式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37757916/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com