PureConfig报错:无法找到pureconfig.ConfigReader[A]隐式实例解决方案问询
问题根因
你当前的写法问题在于:pureconfig.generic.auto._的导入作用域和泛型推导时机不匹配。PureConfig的自动派生是编译期宏逻辑,你把import放在CatalogConfigLoader.load方法内部时,编译器处理load[A]需要ConfigReader[A]实例的阶段,泛型A还未被替换为具体的配置类(比如BookCatalogConfig),宏无法为未知的泛型类型生成对应的Reader实例,因此抛出找不到隐式的编译错误。
适配方案(兼容Scala 2.11 + PureConfig 0.14版本)
两种方案任选,推荐第二种稳定性更高:
方案1:隐式参数透传
将ConfigReader作为隐式参数放到load方法签名,把隐式实例的推导转移到泛型A被确定为具体类型的调用侧。
- 修改
CatalogConfigLoader实现:
import pureconfig.ConfigReader import pureconfig.ConfigReaderFailures import pureconfig.ConfigSource case class CatalogConfigLoader[A <: CatalogConfig](environment: String) { // 隐式参数由调用侧提供 def load()(implicit reader: ConfigReader[A]): A = { ConfigSource.fromConfig(ConfigHelper.getConfig(environment)).load[A] match { case Right(catalogConfig) => catalogConfig case Left(error) => throw new Exception(error.toString()) } } }
- 在调用
load方法的代码处导入自动派生包即可:
import pureconfig.generic.auto._ case class BookCatalog(environment: String) { /* ... */ val config: BookCatalogConfig = CatalogConfigLoader[BookCatalogConfig](environment).load() /* ... */ }
方案2:手动派生隐式Reader(更稳定,推荐)
Scala 2.11的宏派生能力有限,自动派生在泛型上下文容易出现偶发编译失败,手动在配置类的伴生对象中生成Reader不需要依赖导入作用域,兼容性最好:
import pureconfig.generic.semiauto._ import pureconfig.ConfigReader trait CatalogConfig case class TableConfig(database: String, table: String) object TableConfig { implicit val tableConfigReader: ConfigReader[TableConfig] = deriveReader[TableConfig] } case class BookCatalogConfig(author: TableConfig, book: TableConfig) extends CatalogConfig object BookCatalogConfig { implicit val bookCatalogReader: ConfigReader[BookCatalogConfig] = deriveReader[BookCatalogConfig] }
这种方案不需要在调用侧导入pureconfig.generic.auto._,编译器会自动从伴生对象中查找对应的隐式Reader实例,可直接兼容你原有CatalogConfigLoader的调用逻辑。
内容的提问来源于stack exchange,提问作者Adagyo
相关产品推荐
相关产品推荐

