type T = MyClass {def someMethod:String}
這是否意味着編譯器創建像 「trait AnonTrait extends MyClass {def someMethod:String}
」 特質?或者通過其他編譯器機制完成? 我的問題是這種類型語法實際隱藏的內容。
type T = MyClass {def someMethod:String}
這是否意味着編譯器創建像 「trait AnonTrait extends MyClass {def someMethod:String}
」 特質?或者通過其他編譯器機制完成? 我的問題是這種類型語法實際隱藏的內容。
它不會隱藏類型的創建。基本上,它掩蓋了在編譯時使用反射來檢查結構約束,並在運行時調用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。
考慮一下:一個類沒有結構類型。一個類的類型總是一個類。特質產生一個界面。單例對象的類型也是一個類。
結構類型出現在哪裏? 作爲參數和變量的類型。
例如,我可以說def f(s: { def size: Int })
或val r: { def close(): Unit }
。
現在,這些類型如何顯示爲字節碼?像JVM不支持的任何其他類型(例如Java自己的泛型)一樣,它們是已被刪除。
因此,就其他人(即不是斯卡拉)而言,以上s
和r
的類型是java.lang.Object
。
對於Scala本身,一些附加信息存儲在註釋中,Scala可以理解這些信息。
謝謝,所以像java中的反射一樣緩慢地使用這種結構約束?在這些方面,特質是更好的選擇。 – yura
是的,結構類型由於反射而具有性能影響。 –