2013-04-20 133 views
2

混合複雜的Java泛型集合工作在我公司工作,因爲我們從可以概括爲(Java)的模式得到了許多好處如下:在斯卡拉2.10

有「東西」,我們可以得到由他們的特殊/聰明的「ids」。每個「事物」都知道它的ID,而IDS是「聰明的」,因爲你可以讓他們給你所識別的「事物」。在複雜的不斷增長的「事物」層次上,這可以簡化維護過程並消除大量代碼(重複或其他)。我相信你們中的一些人可能會覺得這很奇怪,我可以解釋爲什麼會出現這種情況,但事實是,它是這樣,迄今爲止有幫助,而不是問題的一部分。的這個Java定義

摘要如下(略有改寫):

interface Id<I extends Id<I,T>, T extends Thing<I,T>> { 
    T getThing(); 
    ... 
} 

interface Thing<I extends Id<I,T>, T extends Thing<I,T>> { 
    public I getId(); 
    ... 
} 

有時候,我們需要得到一個給定了一批不同的ID(這正好跨網絡的事情「批」,因此分批加速)。對於本說明書的目的,可以寫成:

public Map<Id<?,?>,Thing<?,?>> getManyThings(List<Id<?,?>> idsToGetThingsFor); 

(方法參數僅僅是ID的多樣性,它真的不要緊,無論它是一個集合,列表或其他方式)

現在,在網絡的另一端,這種方法在Scala 2.9中實現,相當醜陋的避免了Scala泛型的嚴格性。我們正在嘗試升級到Scala 2.10,並且事情不再編譯,必須找出解決方法。訣竅是,有一種方法斯卡拉總結如下:

def getOneThing[I <: Id[I,T],T <: Thing[I,T]](id: I): T; 

這種方法去和檢查,處理和分發適當基於許多因素的呼籲 - 太多在這裏解釋並不相干。

現在,getManyThings()方法遍歷傳遞給它的id並需要將它們作爲參數傳遞給getOneThing()。那是事情失敗的地方。 getManyThings()只知道它獲得的id基本上是Id,並且Scala抱怨[,]對於[I,T],[<] ]]認爲getOneThing()要求:

... error: inferred type arguments [Id[_$16,_$17],Nothing] do not conform to method getOneThing's type parameter bounds [I <: Id[I,T],T <: Thing[I,T]] 

注 - 聲明的標識和東西非參數(非通用)基類並不能真正幫助,因爲它只是推動問題(太多)等景點。我們選擇了非常嚴格的類型以確保代碼質量,但是我們必須有一種方法來處理「混合」集合。

任何幫助?請!

回答

2

我假設你有一個方法是這樣的:

def getManyThings[I <: Id[I, T], T <: Thing[I, T]](ids:List[I]):List[T] = 
    ids map getOneThing 

這會給一個錯誤,因爲編譯器不能推斷出要與T調用getOneThing方法作爲第二個類型參數。

爲了「幫助」你需要明確地傳遞他們的編譯器:

trait Id[I <: Id[I, T], T <: Thing[I, T]] 
trait Thing[I <: Id[I, T], T <: Thing[I, T]] 

def getOneThing[I <: Id[I, T], T <: Thing[I, T]](id:I):T = ??? 

def getManyThings[I <: Id[I, T], T <: Thing[I, T]](ids:List[I]):List[T] = 
    ids map (getOneThing[I, T](_)) 
+0

謝謝!我們只是沒有想到即使這樣做,因爲這是過去的問題(實際的代碼「稍微」更復雜)。它工作在2.10,雖然(和杜!)! – Oopsilon 2013-04-21 18:53:06