【问题标题】:Implicitly aliasing and extending a scala Seq隐式别名和扩展 scala Seq
【发布时间】:2013-03-30 02:46:25
【问题描述】:

我有以下几点:

case class Bar()

trait Foo {
  def bars : Seq[Bar]
}
case class MyFoo(bars : Seq[Bar]) extends Foo

trait Foos extends Seq[Foo] {
  def bars : Seq[Bar] = this.map(_.bars).flatten
}

我想将Seq[MyFoo] 的对象转换为MyFoos,最好是隐式的。怎么可能做到这一点?

例如。

val foos : Foos = Seq(new MyFoo(Seq(new Bar)))

【问题讨论】:

  • 你的意思是trait Bar; trait MyFoo { def bars: Seq[Bar] }
  • 我更新了描述

标签: scala implicit-conversion


【解决方案1】:

你可以这样做:

  case class Bar()

  trait Foo {
    def bars : Seq[Bar]
  }
  case class MyFoo(bars : Seq[Bar]) extends Foo

  trait Foos extends Seq[Foo] {
    def bars : Seq[Bar] = this.map(_.bars).flatten
  }

  implicit def seqMyFooToMyFoos(myFoos:Seq[Foo]) = new Foos {
    def length: Int = myFoos.length

    def apply(idx: Int): Foo = myFoos(idx)

    def iterator: Iterator[Foo] = myFoos.iterator
  }

  val foos : Foos = Seq(new MyFoo(Seq(new Bar))) // Uses implicit conversion

更新

这可能是您正在寻找的更多内容:

  trait Foos {
    def bars : Seq[Bar]
  }

  implicit def seqMyFooToMyFoos(myFoo:Seq[MyFoo]) = new Foos {
    def bars : Seq[Bar] = myFoo.map(_.bars).flatten
  }

  val foos = Seq(new MyFoo(Seq(new Bar)))

  foos.bars

更新 2

如果您使用的是 scala 2.10,则可以使用隐式类并删除 Foos 特征:

  implicit class GetAllBars(myFoo:Seq[MyFoo]) {
    def bars : Seq[Bar] = myFoo.map(_.bars).flatten
  }

  val foos = Seq(new MyFoo(Seq(new Bar)))

  foos.bars

【讨论】:

  • 我更新了描述,虽然我不确定它会改变你的答案。隐式方法是否必须创建一个代理所有 Seq 方法的具体对象?这也不能推断?
  • 因为你需要在 Foos 中扩展 Seq。您可以选择不在 Foos 中扩展 Seq[Foo] ,并且只要您需要进行隐式转换,您将获得默认的 Seq 实现和 bar 方法。
  • 由于我仍然希望最终类型具有 Seq[Foo] 特征,我想我仍然需要在所有 3 种情况下实现这些方法。没关系,虽然我希望有一种方法可以执行类型别名 (type Foos = Seq[Foo]) 之类的操作,但也可以添加一个方法。不过,这个答案很好,谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-02
  • 1970-01-01
  • 2012-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多