2012-10-03 65 views
4

我有兩個對象,每個都有本地定義的類型,我想確定類型是否相同。例如,我想要編譯此代碼:在斯卡拉比較類型

trait Bar { 
    type MyType 
} 

object Bar { 
    def compareTypes(left: Bar, right: Bar): Boolean = (left.MyType == right.MyType) 
} 

但是,編譯失敗,並且「值MyType不是Bar的成員」。

發生了什麼事?有沒有辦法做到這一點?

回答

9

你可以做到這一點,但它需要一點點額外的機械:

trait Bar { 
    type MyType 
} 

object Bar { 
    def compareTypes[L <: Bar, R <: Bar](left: L, right: R)(
    implicit ev: L#MyType =:= R#MyType = null 
) = ev != null 
} 

現在,如果我們有以下幾點:

val intBar1 = new Bar { type MyType = Int } 
val intBar2 = new Bar { type MyType = Int } 
val strBar1 = new Bar { type MyType = String } 

它按預期工作:

scala> Bar.compareTypes(intBar1, strBar1) 
res0: Boolean = false 

scala> Bar.compareTypes(intBar1, intBar2) 
res1: Boolean = true 

訣竅是要求暗示證據L#MyTypeR#MyType是相同的,並提供如果不是,則爲默認值(null)。然後你可以檢查你是否得到默認值。

+0

謝謝,這工作! – emchristiansen

+0

如果沒有使用默認值null,這將是一次完整的編譯時檢查,在這種情況下我更喜歡這種檢查,因爲在編譯時所有類型都是已知的。 – sschaef

+0

@sschaef,我不認爲所有類型在編譯時都是已知的。例如,在下面的bar.MyType直到運行時才確定:「val bar:Bar = if(/ * flip coin * /)intBar1 else strBar1」 – emchristiansen