【问题标题】:How to override an implicit value?如何覆盖隐式值?
【发布时间】:2015-02-28 09:18:02
【问题描述】:

假设我有代码:

class A(implicit s:String = "foo"){println(s)}

object X {
   implicit val s1 = "hello"
}
object Y {
   import X._
   // do something with X
   implicit val s2 = "hi"
   val a = new A
}

我得到错误:

<console>:14: error: ambiguous implicit values:
 both value s2 in object Y of type => String
 and value s1 in object X of type => String
 match expected type String
           val a = new A

有什么方法可以告诉 Scala 在Y 中使用值s2? (如果我将 s2 重命名为 s1,它会按预期工作,但这不是我想要的)。

另一个解决方案是不做import X._,这也是我试图避免的事情。

【问题讨论】:

    标签: scala implicit scala-2.11


    【解决方案1】:

    您可以做的另一件事是导入除s1 之外的所有内容:import X.{s1 =&gt; _, _}

    【讨论】:

    • 感谢您的回答!可能是迄今为止最好的一个。
    【解决方案2】:

    我同意另一个答案,即在这些类型的情况下明确提供隐式是首选,但如果你坚持要“降级”另一个隐式,因此它不再被视为隐式,那么它实际上是可能的:

    class A(implicit s:String = "foo"){println(s)}
    
    object X {
      implicit val s1 = "hello"
    }
    object Y {
      import X._
      val s1 = X.s1 //downgrade to non-implicit
    
      // do something with X
      implicit val s2 = "hi"
      val a = new A
    }
    

    再一次,这有点骇人听闻,但它确实有效。

    【讨论】:

    • 同意.. 有点骇人听闻,但确实可以。
    【解决方案3】:

    试试:

    new A()(s2)
    

    这应该通过 er 显式提供它来覆盖隐式参数。

    【讨论】:

    • 这违背了使用隐式参数的目的。我在几个地方都有new A,我宁愿删除隐含的。
    • @Jus12 我只是不明白你将如何能够保留通配符导入并且至少一次不覆盖显式......
    • implicit 用于像strings 这样的小而客观的事情首先是没有意义的。
    • @SarveshKumarSingh 我同意。 String 只是为了举例。在我的实际代码中,它是一个相当复杂的对象。
    • 并且您在范围内有该复杂对象的多个实例。 Implicits 通常适用于 Helper-functionstypeclass abstract evidences(例如 Monads)或大型且意味着可重复使用的大型对象(例如 ActorSystem)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-29
    • 1970-01-01
    • 2020-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多