2012-05-23 39 views
3

斯卡拉的範圍似乎適用於最大可能表達的隱含級轉化,如下面的例子:Scala的隱級轉化

scala> class B { def b = { println("bb"); true } } 
defined class B 

scala> class A { def a = { println("aa"); new B } } 
defined class A 

scala> (new A).a.b 
aa 
bb 
res16: Boolean = true 

scala> class XXX(b: => Boolean) { def xxx = 42 } 
defined class XXX 

scala> implicit def toXXX(b: => Boolean) = new XXX(b) 
toXXX: (b: => Boolean)XXX 

scala> (new A).a.b.xxx 
res18: Int = 42 

我對這個事實很開心,但我的問題是, SLS的哪一部分指定了這種行爲?爲什麼它不首先評估(new A).a.btrue,並且僅對該值應用轉換?

+0

@Daniel有趣的是,由於此行爲目前使得scalaz的'(file:java.io.File).exists.pure [IO]'按假定的方式工作('io(file.exists)'),否則IO操作會實際上是在IO之外進行的。 – ron

+0

更新:http://groups.google.com/group/scala-language/browse_thread/thread/c8327695dfdceecd – ron

+0

正在進行勸說我建議您使用提供的信息回答您的問題。答案對我有意義。 –

回答

0

由於在郵件列表上回答了瑞恩亨德里克森:

[定義]你正在尋找的是在第7.3節中的三種情況的列表,其中應用的觀點:

  1. 在e類型爲T的選擇em中,如果選擇器不表示T的成員 。在這種情況下,將搜索適用於e的視圖v,其結果 包含名爲m的成員。如隱含 參數那樣,搜索進行,其中隱式範圍是T中的一個。如果找到這樣的視圖,則選擇e.m被轉換爲v(e).m。

所以編譯器只能生成的東西是語義上等價於V(E).M,正如你已經證明,當名稱參數都參與

val x = e 
v(x).m 

不是語義上等效到v(e).m

0

含有隱式轉換

(new A).a.b.xxx 

線被編譯器轉換(即在編譯時)到

toXXX((new A).a.b).xxx 

我們可以看到這一點,如果你在開始時使用-Xprint:typer選項斯卡拉。

private[this] val res3: Int = $line5.$read.$iw.$iw.toXXX(new $line2.$read.$iw.$iw.A().a.b).xxx; 

由於這種轉換髮生在編譯時和不運行時,這將是不可能的斯卡拉應用轉換之前評估(new A).a.btrue。因此,您得到的行爲與您剛剛寫下toXXX((new A).a.b).xxx的行爲完全相同。

+0

但是,防止編譯器轉換成'val x =(new A).a.b; toXXX(x).xxx'?什麼保證觀察到的語義? – ron