关于Scala中类型类的问题

我们有水果,橙子和苹果等课程.

abstract class Fruit
class Orange extends Fruit
class Apple extends Fruit

现在我想为Orange和Apple两种类型添加写入功能.使用类型类模式我可以执行以下操作:

trait Writer[T] {def write(t:T)}

implicit object AppleWriter extends Writer[Apple] {
   def write(a:Apple) {println("I am an apple!")} 
}

implicit object OrangeWriter extends Writer[Orange] {
   def write(o:Orange) {println("I am an orange!")} 
}

def write[T](t:T)(implicit w:Writer[T]){w.write(t)}

所以,好,但如果我想定义writeFruits怎么办?

def writeFruits(fruits:List[Fruit]) {for (fruit <- fruits) write(fruit)}

我想writeFruits可以为每个水果打电话写[Apple]或写[Orange].我看到它不起作用(我知道为什么)但也许我可以实现writeFruits.

我能以某种方式实现writeFruits吗?

解决方法

你只需要选择那些存在Writer的Fruit.不幸的是,一旦你投射到Fruit,你就失去了自动找出哪个是哪个的能力.如果你必须以这种方式设置问题 – 而不是组装一个可写水果列表或某些 – 那么一个合理的选择是使用FruitWriter再次拆分类型:

def writeOne[T](t:T)(implicit w:Writer[T]){w.write(t)}  // New name to avoid shadowing

implicit object FruitWriter extends Writer[Fruit] {
  def write(f: Fruit) { f match {
    case o: Orange => writeOne(o)
    case a: Apple => writeOne(a)
  }}
}

scala> val fruits = List(new Apple,new Orange)
fruits: List[Fruit] = List(Apple@1148ab5c,Orange@39ea2de1)

scala> for (fruit <- fruits) writeOne(fruit)
I am an apple!
I am an orange!

相关文章

共收录Twitter的14款开源软件,第1页Twitter的Emoji表情 Tw...
Java和Scala中关于==的区别Java:==比较两个变量本身的值,即...
本篇内容主要讲解“Scala怎么使用”,感兴趣的朋友不妨来看看...
这篇文章主要介绍“Scala是一种什么语言”,在日常操作中,相...
这篇文章主要介绍“Scala Trait怎么使用”,在日常操作中,相...
这篇文章主要介绍“Scala类型检查与模式匹配怎么使用”,在日...