建议使用scala抽象类型进行锻炼

时间:2015-03-20 11:57:31

标签: scala abstract-type

我正在寻找关于我正在做的这项工作的建议 - 具体来说,哪些方面可以改进/缩短?我不喜欢喂我必须使用的动物 asInstanceOf 但找不到更好的方法。我的想法是,我需要为数百万个对象运行此函数,因此性能非常重要。

P.S。在我的情况下,仿制药会表现得更好吗?

trait Animal {
  type suitableFood
  def eat(f: suitableFood)
}
trait Food
case class Grass (val color: String) extends Food
case class Fish (val size: String, val condition: String) extends Food

trait GrassT{
  type suitableFood = Grass
}
trait FishT{
  type suitableFood = Fish
}
class Cow extends Animal with GrassT{
  def eat (f: suitableFood) = {
    println("moo " + f.color)
  }
}
class Sheep extends Animal with GrassT{
  def eat (f: suitableFood) = {
    println("baaa " + f.color)
  }
}
class Cat extends Animal with FishT{
  def eat (f: suitableFood) = {
    println("mew " + f.size + " " + f.condition)
  }
}
val cow = new Cow
val sheep = new Sheep
val whiteCat = new Cat
val blackCat = new Cat
val fish = new Fish("small", "fresh")
val grass = new Grass("green")
val cats = List(whiteCat, blackCat)
val farmAnimals = List(sheep, cow)
def feedAnimals[F <: Food](food: F, animals: List[Animal]) = {
  animals.foreach(a => a.eat(food.asInstanceOf[a.suitableFood]))
}
feedAnimals(grass, farmAnimals)
feedAnimals(fish, cats)

1 个答案:

答案 0 :(得分:1)

您只需对feedAnimals

进行更严格的类型限制
def feedAnimals[F <: Food](food: F, animals: List[Animal { type suitableFood = F }]) = 
    animals.foreach(_.eat(food))

或者:

def feedAnimals[F <: Food, A <: Animal { type suitableFood = F }](food: F, animals: List[A]) = 
    animals.foreach(_.eat(food))

与使用asInstanceOf的解决方案不同,这些解决方案将在编译时(与运行时相对)在feedAnimals(grass, cats)之类的语句中失败。

如果您愿意,在这种情况下,泛型可能会更简单。