2012-03-07 74 views
14

我有兩個對象,ObjectA和ObjectB,都與一個方法update()。我想寫一個接受ObjectA或ObjectB(但沒有其他類型)的函數。從概念上講,這就是我想要做的事:接受多種類型的參數在斯卡拉

def doSomething[T <: ObjectA | T <: ObjectB](obj: T) = { 
    obj.update 
} 

我知道有其他的方法來解決這個問題(例如,update()方法的結構類型,公共基類等),但我的問題是有可能在Scala中這樣做,如果是這樣的話,語法是什麼?這叫做什麼?

+0

你會怎樣想到這個工作?如果編譯器不知道它是什麼類型,那麼編譯器會知道'T'有什麼方法?如果你的意思是確保你的班級有'update',那麼這就是結構類型的用途。 – dhg 2012-03-08 00:09:23

+4

可能的重複[是否Scala有「類型分離」(聯合類型)?](http://stackoverflow.com/questions/3508077/does-scala-have-type-disjunction-union-types)。接受的答案和下一個排名最高的指向我的unboxed union編碼直接解決了這個問題。 – 2012-03-08 00:28:10

+0

@dhg,如果ObjectA和ObjectB都有一個方法update(),並且type T擴展了這些類中的一個,它可以知道類型T有一個update()方法。 – 2012-03-08 06:28:19

回答

15

在斯卡拉,有一種類型可以做出不相交的聯合。 基本上,你會做這樣的事情:

def doSomething(obj: Either[ObjectA, ObjectB]) { 
    obj.fold(fa, fb) 
} 

結帳http://www.scala-lang.org/api/current/scala/Either.html

+1

如果你想把它們當作一個,你還可以使用結構類型:obj.fold [{def update:Unit}](identity,identity).update' – 2012-03-08 00:17:49

+1

我不知道fa或fb來自哪裏你的例子或你爲什麼要在obj上調用fold(),但似乎是最接近,最乾淨的方式來做到這一點。謝謝。 – 2012-03-08 06:30:38

+0

@Bigwheels它會知道你的問題的上下文,因爲我可能是錯的,但它並沒有真正地使同一個函數應用於兩個可能的對象的工會。基本上,fa和fb是您在ObjectA或ObjectB上適用的閉包。我沒有在我的例子中定義它們。你應該檢查Miles Sabin對沒有使用任何工會的問題的評論,但這是非常技術性的黑客行爲。 – blouerat 2012-03-10 16:34:05