【问题标题】:Purpose of toIterabletoIterable 的目的
【发布时间】:2019-09-29 08:43:49
【问题描述】:

scala exercies我找到了下面的例子:

val set = Set(4, 6, 7, 8, 9, 13, 14)
val result = set.toIterable

带有以下描述:

toIterable 会将任何 Traversable 转换为 Iterable. 这是所有 Scala 集合的基本特征,这些集合定义了一个迭代器方法来遍历集合的元素

但是Set已经是Iterable,那么这个方法有什么意义呢?如果这不是有效的情况,你能给我指一个吗?

【问题讨论】:

    标签: scala collections


    【解决方案1】:

    在 Scala 2.13 中有 no more Traversable:

    更简单的类型层次结构

    不再有TraversableTraversableOnce。它们仅保留为 已弃用 IterableIterableOnce 的别名。

    Set 上调用toIterable 是多余的,因为它只会返回相同的集合:

    此集合为Iterable[A]如果 这已经是Iterable[A]

    toIterable 会产生影响的示例如下:

    "Hello".toIterable
    Array(1).toIterable
    

    隐式转换为

    wrapString("Hello").toIterable
    wrapIntArray(Array(1)).toIterable
    

    并将这些类似 Java 的类型正确地放入 Scala 集合中。

    【讨论】:

    • 那么在 scala 2.13 之前这种方法有什么用途吗?
    • @Andronicus 还有一个目的,例如,Array(1,2,3).toIterable,转换为wrapIntArray(Array(1,2,3)).toIterable 并使Array 这是Scala 对Java 的T[] 的表示Iterable
    【解决方案2】:

    除了 Mario Galic 的回答,它做的另一件事是改变静态类型。如果您和编译器在调用之前就知道它是Set,那么之后您就不知道了。虽然同样可以通过类型归属来实现

    val result: Iterable[Int] = set
    

    (这也适用于字符串和数组),然后你需要写出类型参数,这可能比Int复杂得多。

    我为什么要使用它?如果我知道它是一个 Set,我为什么要将类型更改为 Iterable?

    1. 它可以在一个可以被覆盖并且不必在子类中返回Set的方法中:

      class Super {
        def someValues = {
          val set = ... // you want to avoid duplicates
          set
        }
      }
      
      class Sub : Super {
        override def someValues = {
          List(...) // happens to have duplicates this time
        }
      

      不编译,但如果 Super#someValues 返回 set.toIterable 会编译(尽管通常有明确的返回类型是个好习惯)。

    2. 它可以影响以后推断的类型:

      val arr = Array(set)
      arr(0) = List(0, 1, 2, 3)
      

      不编译,但可以使用Array(set.toIterable)

    【讨论】:

    • 我为什么要使用它?如果我知道它是Set,我为什么要将类型更改为Iterable
    • 我添加了几个例子。
    猜你喜欢
    • 2022-11-11
    • 2016-06-03
    • 1970-01-01
    • 1970-01-01
    • 2015-10-06
    • 2014-01-30
    • 2011-09-26
    • 2019-12-17
    • 2017-12-26
    相关资源
    最近更新 更多