【问题标题】:Scala create method at run time from a string and invoke itScala 在运行时从字符串创建方法并调用它
【发布时间】:2018-05-08 13:50:06
【问题描述】:

有什么方法可以在 scala 中从字符串创建方法然后调用它?例如

val code = "(a: String, b:String) => {a+b}"

我想知道是否有任何方法可以实例化该方法并调用它?

我已经探索了 toolbox 和 twitter util eval,它们都需要我编译和实例化方法 asInstanceOf[(String, String) => Option[Any]]

为此,我需要知道参数及其类型,我正在寻找不需要事先知道参数类型的方法。

【问题讨论】:

  • 那么可以使用(Any, Any) => Nothing
  • 我也不知道参数的数量,因为代码来自其他地方。
  • 那你打算怎么称呼它?你能提供更多背景信息吗?
  • 听起来你在寻找 Python? :)
  • 听起来你真正需要的是你自己的表达语言和你的 scala 应用程序中该语言的解析器。

标签: scala reflection


【解决方案1】:

看看 twitter util eval api

import com.twitter.util.Eval 
val func = new Eval().apply[(String, String)=>String]("(a: String, b:String) => a+b")



scala> func("ab", "cd")
res1: String = abcd

【讨论】:

  • 谢谢,但是当我将这样创建的函数用作 Spark 中的 UDF 时,它会因 java.lang.ClassCastException: cannot assign instance of scala.collection.immutable.List$SerializationProxy to field org 而失败。 org.apache.spark.rdd.MapPartitionsRDD 实例中 scala.collection.Seq 类型的 apache.spark.rdd.RDD.org$apache$spark$rdd$RDD$$dependencies_
  • 不确定你是如何编写代码的,实际上下面的示例代码似乎在我的 spark 本地模式下工作:` rdd.mapPartitions{ x => import com.twitter.util.Eval val func = new Eval( ).apply[(String, String)=>String]("(a: String, b:String) => a+b") x.map( y => func(y.toString, y.toString) ) } `
  • val func = new Eval().apply[(String, String)=>String]("(a: String, b:String) => a+b") sparkSession.sqlContext.udf .register("concatUDF", func) val sqlDF2 = sparkSession.sql("SELECT concatUDF(name, name) as welcome FROM employee") sqlDF2.show()
  • 它抛出一个异常 - java.lang.ClassCastException: cannot assign instance of scala.collection.immutable.List$SerializationProxy to field org.apache.spark.rdd.RDD.org$apache$spark org.apache.spark.rdd.MapPartitionsRDD 实例中的 scala.collection.Seq 类型的 $rdd$RDD$$dependencies_
  • 只有当我从动态编译的函数注册 udf 时才会发生这种情况,例如你给出的例子。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-09
  • 1970-01-01
相关资源
最近更新 更多