在运行时解析隐式参数

Resolving implicit parameter at runtime

我知道编译期间会解决隐式问题,所以我想我正在寻找以下问题的解决方法。假设我有一个带有此签名的方法:

class MyClass {
  def run[X](x: X)(implicit runnable: Runnable[X]) = runnable(x)
}

我要包起来:

class MyClassWrapper[Z: ClassTag] {
  val rdd: RDD[Z] = //Spark RDD
  def runWrapper[X](fun: Z => X) = rdd.foreach( (el:Z) => new MyClass.run(fun(el)))
}

这不会编译抱怨找不到隐含的。我可以将签名更改为:

def runWrapper[X](fun: Z => X)(implicit runnable: Runnable[X])

所有都可以编译,但我使用的是 Spark,它不允许从外部在操作中捕获不可序列化的对象(在我的例子中,run 将从 runWrapper) 所以我确实需要 get/create 隐含 inside run 而不是从外部关闭它。那可能吗?

您可以尝试实例化 foreach 中的隐式:

def runWrapper[X](fun: Z => X) = rdd.foreach{ (el:Z) => 
   val runnable = implicitly[Runnable[X]]
   new MyClass.run(fun(el))(runnable)
}

无法在运行时想出任何东西(不想尝试反射)所以我最终写了几个版本的方法,每个类型一个(因为它们不共享任何共同的父级)

class MyClassWrapper[Z: ClassTag] {
  val rdd: RDD[Z] = //Spark RDD
  def runWrapper(fun: Z => Implementation1) = rdd.foreach( (el:Z) => new MyClass.run(fun(el)))

  def runWrapper(fun: Z => Implementation2) = rdd.foreach( (el:Z) => new MyClass.run(fun(el)))
}