如何在 class 范围内更喜欢方法范围内的隐式?

How to prefer implicit in method scope over class scope?

我有一个类似于下面代码的 Scala 代码。在 class / 对象级别有一个隐式定义,我想 'override' 它具有方法中定义的隐式。 (如果你真的需要知道,我需要专门针对有问题的方法更改我的 ExecutionContext)。

在这个例子中,我想在 bar 方法的范围内使用 b 作为 Int 的隐式。我该怎么做?

object Foo {
  implicit val a: Int = 1
  def bar: Int = { // Didn't pass implicit Int parameter
    implicit val b: Int = 2
    implicitly[Int]
  }
}

这抱怨

error: ambiguous implicit values: both value a in object Foo of type Int and value b of type Int match expected type Int

所以我认为 Scala 无法在 class 作用域隐式和方法作用域隐式之间进行选择。

在 dotty/scala 3 中应该已经按您的预期运行 (second bullet point)。在 Scala 2 中,您必须通过给它们相同的名称来隐藏外部作用域中的隐式。

object Foo {
  implicit val a: Int = 1
  def bar: Int = {
    implicit val a: Int = 2
    implicitly[Int] // 2
  }
}

这是在使用 Scala 2 编译 Scala 3 编译器时使用的策略:http://dotty.epfl.ch/docs/internals/contexts.html#using-contexts

您不能在当前的 Scala 2 中执行此操作。至少没有不明确的方法(hack),例如阴影。

因为方法作用域或class成员作用域或代码块作用域之间没有区别。您只有两个范围 - 本地范围和相应类型的范围。您可以阅读有关 there (Implicit Scope and Implicit Resolution).

的内容

你可以做什么来达到想要的结果?

您可以将您的代码移动到另一个范围。例如。新创建的静态对象。

object Foo {
  implicit val a: Int = 1
  val b: Int = 2
  def bar: Int = AnotherScopeObject.bar(b)
}

object AnotherScopeObject {
  def bar(implicit implicitInt: Int) : Int = {
    implicitly[Int]
  }
}