2016-09-29 29 views
1

下面的代碼將不能編譯,爲什麼不斯卡拉與泛型類的情況下密封延伸特質

class FruitProcessor[T <: Fruit] { 
    def process(fruit: T) = { 
    // Do something with fruit 
    } 
} 

class FruitBlender[T <: Fruit] { 
    val fruitProcessor = new FruitProcessor[T] 

    def blend(fruit: T) = { 
    fruit match { 
     case b: Banana => fruitProcessor.process(b) 
     case a: Apple => fruitProcessor.process(a) 
    } 
    } 
} 


sealed trait Fruit 
case class Banana(id: String) extends Fruit 
case class Apple(id: String) extends Fruit 

的編譯錯誤是沿着線的我不明白原因「發現香蕉,需要T」

我在這裏做錯了什麼?

+0

放下'T',並將其替換爲'Fruit'。 – Reactormonk

回答

3

process方法需要T類型的參數,但是您將其傳遞給類型爲Banana的值。編譯器不夠聰明,因爲在調用fruitProcessor.process(b)的代碼路徑中,T始終是Banana。其實你根本不需要那個匹配表達。在這種情況下,方法blend中的Tprocess想要的T相同。所以你可以撥打fruitProcessor.process(fruit)

1

拼出你做什麼: 你有一個FruitProcessor參數與子類的FruitT,它可以processT秒。 然後,您製作FoodBlender也參數化了的子類T,它具有FoodProcessor[T],即它可以process各種T

既然你只能processT而不是[S <: Fruit],即只有你的FruitT亞型,其中攪拌器是參數化,而不是所有Fruit S的特定情況下,這不能與特定類型BananaApples工作。 FruitBlender上的T例如可以是class Pear extends Fruit,並且在那種情況下,blend的簽名將是def blend(fruit: Pear),當然這與Apples或Bananas不兼容。