建议使用 scala 抽象类型进行练习

Advise on exercise with scala abstract types

我正在寻找关于我正在做的练习的建议 - 具体来说,哪些区域可以 improved/shortened?我不喜欢用 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)

你只需要对 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) 等语句失败。

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