[英]Importing generic implicits from class instances
我正在尝试创建一个通用的隐式提供程序,该提供程序可以为给定类型创建隐式值,如下所示:
trait Evidence[T]
class ImplicitProvider[T] {
class Implementation extends Evidence[T]
implicit val evidence: Evidence[T] = new Implementation
}
要使用此隐式,我在必要时创建一个val provider = new ImplicitProvider[T]
实例,并从中import provider._
。 只要只有一个实例,此方法就可以正常工作。 但是有时在一个地方需要几种类型的隐式
case class A()
case class B()
class Test extends App {
val aProvider = new ImplicitProvider[A]
val bProvider = new ImplicitProvider[B]
import aProvider._
import bProvider._
val a = implicitly[Evidence[A]]
val b = implicitly[Evidence[B]]
}
而且无法编译, could not find implicit value for parameter
而not enough arguments for method implicitly
错误not enough arguments for method implicitly
。
如果我直接使用提供程序的隐式val,那么一切都会再次开始工作。
implicit val aEvidence = aProvider.evidence
implicit val bEvidence = bProvider.evidence
但是,我试图避免导入单个值,因为每个提供程序中实际上都有多个隐式对象,目标是在可能的情况下抽象它们。
可以通过某种方式实现,还是我希望编译器提供太多?
问题是,当你从两个对象导入,你就带来两个实体已经发生碰撞的名字: evidence
在aProvider
和evidence
在bProvider
。 编译器不能消除它们的歧义,这不仅是因为其实现方式,而且因为对于隐式对象(可能已经是奥秘的)而言,要能够执行无法显式完成的工作(在冲突的名称之间进行歧义化),这不是一个好主意。
我不明白的是ImplicitProvider
的意义是什么。 您可以拉动Implementation
类向顶层,有一个object
的地方,保持implicit val
秒。
class Implementation[T] extends Evidence[T]
object Evidence {
implicit val aEvidence: Evidence[A] = new Implementation[A]
implicit val bEvidence: Evidence[B] = new Implementation[B]
}
// Usage:
import Evidence._
implicitly[Evidence[A]]
implicitly[Evidence[B]]
现在,没有名称冲突。
如果您需要一个实际的ImplicitProvider
,则可以执行以下操作:
class ImplicitProvider[T] { ... }
object ImplicitProviders {
implicit val aProvider = new ImplicitProvider[A]
implicit val bProvider = new ImplicitProvider[B]
implicit def ImplicitProvider2Evidence[T: ImplicitProvider]: Evidence[T]
= implicitly[ImplicitProvider[T]].evidence
}
// Usage
import ImplicitProviders._
// ...
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.