【问题标题】:Why are there so many Scala collection view types?为什么有这么多 Scala 集合视图类型?
【发布时间】:2013-04-10 12:38:29
【问题描述】:

我是 Scala 新手,所以我想了解为什么对视图的调用会返回 IndexedSeqViewS 和类似类的实例。为什么每个操作都需要不同的类?

【问题讨论】:

    标签: scala collections lazy-evaluation


    【解决方案1】:

    因为每个视图转换器操作(即生成新视图的操作,例如 mapfilterslice)都会创建一个以不同方式遍历基础集合的视图。 请注意,IndexedSeqViewS 不是该集合类的实际名称 - 它是 toString 返回的美化名称。

    例如,Mapped 视图创建基础集合的视图,以便基础集合的每个元素都以某种方式进行转换。

    这需要重新定义foreach,如下所示:

      trait Mapped[B] extends Transformed[B] {
        // ...
        def foreach[U](f: B => U) {
          for (x <- self)
            f(mapping(x))
        }
        // ...
      }
    

    Filtered 视图需要在遍历时忽略一些元素:

      trait Filtered extends Transformed[A] {
        // ...
        def foreach[U](f: A => U) {
          for (x <- self)
            if (pred(x)) f(x)
        }
        // ...
      }
    

    由于集合具有基于继承的设计,要覆盖foreach 的定义(以及applysize 等其他方法),需要引入子类。在一些替代设计中,例如一个基于类型类的,可能必须引入一个单独的类型类来重新定义特定类型的foreach

    【讨论】:

    • 每个Stream[T]操作是否有单独的类?
    • 不,每个 Stream 操作只有 2 个类——空流和流缺点。但是,这些操作总是返回一个Stream——并且每个流都使用相同的foreach 实现进行遍历。 *View 操作是独立于集合的——视图链中底层集合 (foreach) 的遍历根据先前调用的操作而变化——以及其他访问器操作(如 reduce、@987654342 @ 或 copyToArray) 以 foreach 的形式实现。
    • 如果您要包含所有可能的视图转换的所有信息,您可以避免使用一类操作模式——即用一个大的flatMapFilterGroupBySlice 表示所有视图转换包含所有可能的转换信息的方法。
    猜你喜欢
    • 2023-03-14
    • 2019-10-12
    • 2016-06-04
    • 2011-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-19
    • 2017-06-22
    相关资源
    最近更新 更多