我一直試圖弄清楚隱式參數如何在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