我有一个类似于下面代码的Scala代码。在类/对象级别定义了一个隐式,我想用方法中定义的隐式"重写"它。(如果你真的需要知道,我需要专门为有问题的方法更改我的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]
}
}
这与有关
错误:不明确的隐式值:Int类型的对象Foo中的两个值a和Int类型的值b匹配预期类型Int
所以我认为Scala不能在类范围隐式和方法范围隐式之间做出选择。
在dotty/scala 3中,它应该已经按您的预期工作了(第二个要点(。在Scala 2中,您必须为外部作用域中的隐式赋予相同的名称,从而对其进行阴影处理。
object Foo {
implicit val a: Int = 1
def bar: Int = {
implicit val a: Int = 2
implicitly[Int] // 2
}
}
这是Scala 3编译器实现中使用的策略,当它使用Scala 2编译时:http://dotty.epfl.ch/docs/internals/contexts.html#using-上下文
在当前的Scala 2中无法做到这一点。至少没有不明确的方法(黑客(,如阴影。
因为方法作用域、类成员作用域或代码块作用域之间没有区别。您只有两个作用域——本地作用域和相应类型的作用域。你可以在那里阅读(隐式范围和隐式解决方案(。
你能做些什么来达到想要的结果?
您可以将代码移动到另一个范围。例如,新创建的静态对象。
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]
}
}