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

时间:2015-04-24 02:17:55

标签: 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)
  }

这里我将fun1传递给fun2,编译器抱怨它无法找到fun1的隐含值。

  fun2(fun1,"asdfasdf")    //error here,   fun1 is lack of an implicit value

我想通过改变fun2的形状来解决问题,即

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

但我不知道怎么写得正确。

补充:

声明一个隐式格式似乎是一个很好的解决方案。但我必须在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)
        ......
        }
  }

formats必须在lines的{​​{1}}函数内定义(我使用map代替)。

1 个答案:

答案 0 :(得分:1)

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(_)(_))
但是,哎呀;呼叫网站不如您想要的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)

是的,干净的通话网站!

这符合您的要求吗?在您的问题中,Formats正文中的隐式范围内只有fun2,但我无法判断这是否是您问题的必要条件,或者只是您凝结的方式意外你的代码适合问题。