如何间接传递隐式参数

时间:2017-03-11 06:56:01

标签: scala implicit

我希望下面的代码打印出12。但我得到defaultdefault。当我使用注释掉的代码显式转发(?)隐式值时,我看到了所需的输出。谁能解释一下这是如何工作的?我尝试的不可能吗?我对Scala来说是全新的。我应该阅读什么来深入理解这一点?

case class Context(id: Option[String])
object Context {
  implicit val context = Context(Some("default"))
}

class ToolBuilder (id: String) {
  implicit val context = Context(Some(id))
  def extract() = ToolCreatorA.create()
}

case class ToolCreatorA(id: String)
object ToolCreatorA {
  def create() = ToolCreator.create()
  //def create()(implicit context: Context) = ToolCreator.create()
  object ToolCreator {
    def create()(implicit context: Context) = context.id.getOrElse("null")
  }
}

object Main {
  def main(args: Array[String]): Unit = {
    println(new ToolBuilder("1").extract())
    println(new ToolBuilder("2").extract())
  }
}

1 个答案:

答案 0 :(得分:3)

scala documentation of implicit开始,这些是确定隐式参数值的两个规则。

  

首先,符合条件的是所有标识符x,它们可以在没有前缀的方法调用点访问,并且表示隐式定义或隐式参数。

     

其次,符合条件的也是隐式参数类型的伴随模块的所有成员,这些模块被标记为隐式。

因此,在您的情况下,让我们先看看使用def create() = ToolCreator.create()时会发生什么。在此处,ToolCreator.create()会调用伴随对象create的{​​{1}}方法,该方法需要隐式ToolCreator Context

  1. 现在我们的第一条规则说,该方法将在方法调用发生之前在其访问的所有变量中查找隐式参数。我们看到那时没有可用的隐式变量。
  2. 然后第二个规则是,在隐式类型的伴随对象中查找隐式变量。在我们的例子中,隐式是def create()(implicit context: Context) = context.id.getOrElse("null")类型,我们有一个Context伴随对象,它定义了一个很好的隐式变量。因此,该值将在Context方法中获取。 create
  3. 现在,如果我们使用 object Context { implicit val context = Context(Some("default")) },则从

    调用此create方法

    def create()(implicit context: Context) = ToolCreator.create()

  4. 正如您所看到的,在调用class ToolBuilder (id: String) { implicit val context = Context(Some(id)) def extract() = ToolCreatorA.create() }方法之前,它有一个可用作隐式的上下文变量。所以这个价值会被提升。

  5. 有用的链接:

    1. Understanding implicit in Scala

    2. http://www.drmaciver.com/2008/03/an-introduction-to-implicit-arguments/

    3. http://www.artima.com/pins1ed/implicit-conversions-and-parameters.html#21.5