2011-08-31 141 views
5

例子:什麼是結構類型scala語法定義的actuall類?

type T = MyClass {def someMethod:String} 

這是否意味着編譯器創建像 「trait AnonTrait extends MyClass {def someMethod:String}」 特質?或者通過其他編譯器機制完成? 我的問題是這種類型語法實際隱藏的內容。

回答

3

它不會隱藏類型的創建。基本上,它掩蓋了在編譯時使用反射來檢查結構約束,並在運行時調用someMethod。

舉例來說,如果您有:

class Foo(t: MyClass {def someMethod:String}) { 
    def CallSomeMethod = t.someMethod 
} 

這意味着您的Foo類的構造函數接受MyClass類型也有一個的someMethod(其中的someMethod可以通過特質混入MyClass的)的噸。 你可以有:

class MyClass {} 
trait WithSomeMethod {def someMethod = "hello"} 

,你可以再像這樣創建富:現在

val mc = new MyClass with WithSomeMethod 
val foo = new Foo(mc) 
println(foo.CallSomeMethod) // prints "hello" 

,當您創建new Foo(mc)編譯器使用反射來檢查MC的是,也有一個的someMethod一個MyClass的。實際呼叫foo.CallSomeMethod也通過反思進行工作。

現在(多多包涵,我得到你的實際問題...)這樣做,你做的事:

type T = MyClass {def someMethod:String} 

只創建一個類型別名,而不是一個具體類型。一旦你有這樣的定義T,你可以定義Foo爲:

class Foo(t: T) { 
    def CallSomeMethod = t.someMethod 
} 

這相當於先前給出的Foo的定義。您剛剛創建了一個別名T,可以在您可能使用過的其他地方重複使用MyClass {def someMethod:String}。沒有生成實際的T類型,並且每當引用T時編譯器仍然使用反射,以檢查它確實具有定義的someMethod的結構約束,並且仍然基於反射生成代碼以調用someMethod。

+0

謝謝,所以像java中的反射一樣緩慢地使用這種結構約束?在這些方面,特質是更好的選擇。 – yura

+0

是的,結構類型由於反射而具有性能影響。 –

3

它沒有創建一個Trait,它只是一個類型別名,這意味着每次你參考T時,你其實都提到了MyClass {def someMethod:String}。但是,您可以使用特徵覆蓋類型聲明:

trait A 

class B { 
    type T <: A 
} 

class SubB { 
    trait T extends A 
} 
+0

我的問題是這種類型的語法實際上隱藏了什麼。 – yura

+0

我的答案是:一個類型別名。 – Nicolas

3

考慮一下:一個類沒有結構類型。一個類的類型總是一個類。特質產生一個界面。單例對象的類型也是一個類。

結構類型出現在哪裏? 作爲參數和變量的類型。

例如,我可以說def f(s: { def size: Int })val r: { def close(): Unit }

現在,這些類型如何顯示爲字節碼?像JVM不支持的任何其他類型(例如Java自己的泛型)一樣,它們是已被刪除

因此,就其他人(即不是斯卡拉)而言,以上sr的類型是java.lang.Object

對於Scala本身,一些附加信息存儲在註釋中,Scala可以理解這些信息。

相關問題