代码之家  ›  专栏  ›  技术社区  ›  Vasiliy Ivashin

从类实例导入泛型隐式

  •  0
  • Vasiliy Ivashin  · 技术社区  · 7 年前

    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 错误。

    如果我直接使用提供者的隐式VAL,一切都会重新开始工作。

    implicit val aEvidence = aProvider.evidence
    implicit val bEvidence = bProvider.evidence
    

    然而,我试图避免导入单个值,因为每个提供程序中实际上有几个隐式,目标是尽可能地抽象它们。

    这可以通过某种方式实现吗?还是我想从编译器中获得太多?

    1 回复  |  直到 7 年前
        1
  •  1
  •   HTNW    7 年前

    evidence 在里面 aProvider bProvider . 编译器无法消除这些歧义,既因为它是如何实现的,也因为隐式是一个坏主意,隐式可能已经很神秘,能够做无法显式完成的事情(消除冲突名称之间的歧义)。

    ImplicitProvider Implementation 让学生达到最高水平,并进行 object implicit val s

    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]]
    

    如果你需要一个实际的 隐式提供者 ,您可以这样做:

    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._
    // ...