建议使用 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)
等语句失败。
如果您愿意,泛型在这种情况下可能更简单。
我正在寻找关于我正在做的练习的建议 - 具体来说,哪些区域可以 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)
等语句失败。
如果您愿意,泛型在这种情况下可能更简单。