如何在 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]
}
}
我有一个类似于下面代码的 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]
}
}