微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

关于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!

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐