我一直试图弄清楚隐式参数如何在Scala中工作。据我可以告诉隐式参数分辨率是这样的:Scala中的惰性vals和隐式参数
- 显式传递一个对象的方法。
- 在范围中定义的隐式定义。作为一个隐含参数
然而类的
class Bar(val name:String)
object Bar { implicit def bar = new Bar("some default bar") }
class Foo {
lazy val list = initialize
def initialize(implicit f:Bar) = {
println("initialize called with Bar: '" + f.name + "' ...")
List[Int]()
}
}
trait NonDefaultBar extends Foo {
implicit def f = new Bar("mixed in implicit bar")
def mixedInInit = initialize
lazy val mixedInList = list
}
object Test {
def test = {
println("Case 1: with implicitp parameter from companion object")
val foo1 = new Foo
foo1.list
foo1.initialize
println("Case 2: with mixedin implicit parameter overriding the default one...")
val foo2 = new Foo with NonDefaultBar
foo2.mixedInList
val foo3 = new Foo with NonDefaultBar
foo3.mixedInInit
println("Case 3: with local implicit parameter overriding the default one...")
implicit def nonDefaultBar = new Bar("locally scoped implicit bar")
val foo4 = new Foo
foo4.list
foo4.initialize
}
}
调用Test.test
给出了下面的输出:
Case 1: with implicitp parameter from companion object
initialize called with Bar: 'some default bar' ...
initialize called with Bar: 'some default bar' ...
Case 2: with mixedin implicit parameter overriding the default one...
initialize called with Bar: 'some default bar' ...
initialize called with Bar: 'mixed in implicit bar'...
Case 3: with local implicit parameter overriding the default one...
initialize called with Bar: 'some default bar' ...
initialize called with Bar: 'locally scoped implicit bar' ...
为什么编译器抓不住,有案例2调用mixedInList当混合隐吧。在情况3中,它在访问列表时也忽略了本地定义的隐式条。
是否有任何方法使用隐式参数与惰性vals不使用隐式定义的伴随对象?
好吧,但*不应该*它承认implicits?它们在编译时是已知的吗?也许它会工作,如果我将隐式参数移动到构造函数? – 2012-04-15 14:36:37
它识别编译时在范围内唯一隐含的Bar,这是Bar伴侣中的一个。因为'list'只在'Foo'上定义,所以它会一直使用这个。您可以在您的构造函数中定义隐式,但特征中的隐式仍然不在作用域中,因为它只存在于实例上。 – drexin 2012-04-15 14:59:10
因此,如果我将惰性val和初始化方法移动到NonDefaultBar特性并让该特性扩展Foo并将隐式def移动到Foo,那么编译器会知道在Foo中获取隐式def '评估'懒惰的列表'? – 2012-04-15 16:00:41