【问题标题】:Overriding methods map and flatMap in class extending trait Iterator在扩展 trait Iterator 的类中覆盖方法 map 和 flatMap
【发布时间】:2015-06-25 09:08:16
【问题描述】:

作为一名 Scala 初学者,我正在尝试为在 for 表达式中检索和处理的 Iterator 的每个项目实现一个计数器,并且每次在“循环之一”上进行新迭代时都会增加一个计数器" 开始表达式(外循环和嵌套循环)。要求是在不简单地在for 表达式中的多个位置放置类似counter = counter + 1 的语句来完成此操作。 下面的清单显示了我对这个问题提出的解决方案,我想知道,为什么方法 next 实现 Iterator 的抽象成员被调用(并且相应的计数器增加)而 flatMapmap 覆盖它们在 trait Iterator 中定义的挂件(并通过 super 调用它们)根本不会被调用。

object ZebraPuzzle {
  var starts = 0
  var items = 0

  class InstrumentedIter[A](it: Iterator[A]) extends Iterator[A] {
    private val iterator = it

    def hasNext = it.hasNext

    def next() = {
      items = items + 1
      it.next()
    }

    override def flatMap[B](f: (A) ⇒ GenTraversableOnce[B]): Iterator[B] = {
      starts = starts + 1
      super.flatMap(f)
    }

    override def map[B](f: (A) ⇒ B): Iterator[B] = {
      starts = starts + 1
      super.map(f)
    }
  } // inner class InstrumentedIter 

对应的for 表达式如下所示:

  def solve = {
    val first = 1
    val middle = 3
    val houses = List(first, 2, middle, 4, 5)
    for {
      List(r, g, i, y, b) <-  new InstrumentedIter(houses.permutations)
      if ...
      List(eng, span, ukr, jap, nor) <- new InstrumentedIter(houses.permutations)
      if ...
      if ...
      if ...
      List(of, tea, milk, oj, wat) <- new InstrumentedIter(houses.permutations)
      if ...
      ...
    } yield ...
  ...
  }
...
} // standalone singleton object ZebraPuzzle

如果有人能给我提示如何以更好的方式解决给定的问题,我将不胜感激。但最重要的是,我很想知道为什么我的解决方案覆盖了IteratormapflatMap 并没有像我有限的大脑所期望的那样工作;-)

问候

马丁

【问题讨论】:

  • 请写出别人可以编译运行的代码。我没有兴趣回答问题,因为我首先必须思考几分钟给定的代码应该做什么。

标签: scala inheritance collections iterator-traits


【解决方案1】:

与此同时,我自己设法找到了答案。我的解决方案的问题是 withFilter 返回对新创建的 AbstractIterator 的引用,而不是 InstrumentedIterator。作为一种可能的解决方案,可以将此引用传递给包装类的构造函数,例如 InstrumentedIterator,它混合了 trait Iterator 并覆盖方法 map 和 flatMap。然后这些方法可以进行计数...

问候 马丁

【讨论】:

    【解决方案2】:

    你的台词

    List(...) <- Iterator
    

    不要调用 map 和 flatmap。他们在 List 伴生对象中调用 unapply,将迭代器解包成元组。

    要调用 map 或 flatMap 你需要类似的东西

    item <- Iterator
    

    您需要使用 unapply 方法为 InstrumentedIter 定义一个伴随对象,或者在您的理解中使用 map/flatMap 语法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-08-04
      • 2011-03-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多