如何使用隐式参数传递函数

wor*_*tor 5 scala implicit-conversion

我想将一个函数fun1作为参数传递给fun2.但是fun1需要一个隐含参数.是否可以在里面定义隐含值fun2

代码是这样的:

import org.json4s._
import org.json4s.jackson.JsonMethods._

  def fun1(json:JValue)(implicit formats: Formats) = {

        //do something
  }


  def fun2(f: (JValue) => RatEvent,line:String ) = {

        implicit val formats = DefaultFormats  //has been defined in import
        val json = parse(line)  //covert string to jvalue
        val result = f(json)
  }
Run Code Online (Sandbox Code Playgroud)

在这里我传递fun1fun2,编译器抱怨它找不到fun1的隐含值.

  fun2(fun1,"asdfasdf")    //error here,   fun1 is lack of an implicit value
Run Code Online (Sandbox Code Playgroud)

我想通过改变fun2ie 的形状来解决问题

def fun2(f: (JValue)(implicit Formats) => RatEvent,line:String ) //doesn't compile
Run Code Online (Sandbox Code Playgroud)

但我不知道如何正确地写它.

补充:

声明一个隐式格式似乎是一个很好的解决方案.但我必须在fun2中定义它.我让问题变得简单.真正的乐趣看起来像:

  def fun2(f: (JValue) => RatEvent,lines:RDD[String] )(implicit sc:SparkContext) = {

        for (
          line <- lines
        ){
        implicit val formats = DefaultFormats  //has been defined in import
        val json = parse(line)  //covert string to jvalue
        val result = f(json)
        ......
        }
  }
Run Code Online (Sandbox Code Playgroud)

formats已到的内部被定义linesmap函数(I使用for代替).

Set*_*sue 2

Scala 函数值的apply方法只有一个参数列表,并且不采用任何隐式参数。你对此无能为力。

您可以更改 的形状fun2以将额外参数作为普通参数:

class J; class F; class R

def fun1(j: J)(implicit f: F): R =
  new R
def fun2(fn: (J, F) => R) {
  fn(new J, new F)
}

fun2(fun1(_)(_))
Run Code Online (Sandbox Code Playgroud)

但是恶心;呼叫站点并不像fun2(fun1)您想要的那么好。

如果调用站点的范围内有隐式 F,则可以更改 的形状,fun2如下所示:

class J; class F; class R

def fun1(j: J)(implicit f: F): R =
  new R

def fun2(fn: J => R)(implicit f: F) {
  fn(new J)
}

implicit val f = new F
fun2(fun1)
Run Code Online (Sandbox Code Playgroud)

是的,干净的呼叫站点!

这满足您的要求吗?在你的问题中,你只有一个Formats隐式范围内的主体fun2,但我无法判断这是否是你的问题的必要条件,或者只是你压缩代码以适应问题的方式的意外情况。