我正在尝试使用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尝试了这个。
答案 0 :(得分:2)
您的通话需要一个隐含的Extractor[T]
,其中对T
一无所知。从伴侣对象中解析它 ,如果有的话,但是那里没有这样的方法。
想象一下它有效。然后
val cfg = new Config
val x = cfg.extract[String]("foo", "")
也应该编译。但如果没有隐含的Extractor[String]
,它将如何运作?