在方法调用

时间:2016-09-15 06:31:33

标签: scala

我正在尝试使用implicit类和类型类向配置库添加辅助方法。但是,我对Scala非常新(1周)并且无法找出以下代码发出编译错误的原因(我在代码中的注释中提供了工作解决方案)

简化第三方包裹:

package pkg

class Config {
  def hasPath(path: String) = { false }
  def getString(path: String) = { "str" }
  def getInt(path: String) = { 7 }
  def getDouble(path: String) = { 3.14d }
}

我的示例文件:

import pkg._

object Helpers {

  trait Extractor[T] {
    def extract(cfg: Config, path: String): T
  }

  object Extractor {

    implicit object IntExtractor extends Extractor[Int] {
      def extract(cfg: Config, path: String) = {
        99
      }
    }

  }

  implicit class BetterConfig(cfg: Config) {

    def extract[T](path: String)(implicit extractor: Extractor[T]): T = {
      extractor.extract(cfg, path)
    }

    // This example works if I add the implicit parameter:
    // (implicit extractor: Extractor[T])
    def extract[T](path: String, default: T): T = {
      if ( cfg.hasPath(path) ) {
        extract[T](path)
        //        ^ error here
      } else { 
        default
      }
    }
  }
}


object Demo extends App {

  import Helpers._

  val cfg = new Config
  val x = cfg.extract("foo", 3)

  println(s"x: ${x}")
}

此代码提供错误could not find implicit value for parameter extractor: Helpers.Extractor[T]

为什么在extract(path)内调用extract(path, default)时无法找到隐含值?我对范围规则的理解或解决隐含的,是错误的。我原以为当extract(path)内的extract(path, default)调用是在Extractor内进行的时,隐式仍会从Key Value Jack [a,b,c] 的伴随对象中解析出来。

我用Scala 2.10.6和2.11.8尝试了这个。

1 个答案:

答案 0 :(得分:2)

您的通话需要一个隐含的Extractor[T],其中对T一无所知。从伴侣对象中解析它 ,如果有的话,但是那里没有这样的方法。

想象一下它有效。然后

val cfg = new Config
val x = cfg.extract[String]("foo", "")

也应该编译。但如果没有隐含的Extractor[String],它将如何运作?