代码之家  ›  专栏  ›  技术社区  ›  user3663882

GenericTraversableTemplate::扁平化。它有什么魔力?

  •  0
  • user3663882  · 技术社区  · 10 年前

    我想知道 flatten this article

    def toInt(s: String): Option[Int] = {
        try {
            Some(Integer.parseInt(s.trim))
        } catch {
            // catch Exception to catch null 's'
            case e: Exception => None
        }
    }
    
    scala> val strings = Seq("1", "2", "foo", "3", "bar")
    strings: Seq[java.lang.String] = List(1, 2, foo, 3, bar)
    
    scala> strings.map(toInt)
    res0: Seq[Option[Int]] = List(Some(1), Some(2), None, Some(3), None)
    
    scala> val flattenResult = mapResult.flatten
    flattenResult: Seq[Int] = List(1, 2, 3)
    

    哇!这看起来像是奇迹。如何 压平 方法知道我们不应该添加 None

    def flatten[B](implicit asTraversable: A => /*<:<!!!*/ GenTraversableOnce[B]): CC[B] = {
        val b = genericBuilder[B]
        for (xs <- sequential)
          b ++= asTraversable(xs).seq
        b.result()
      }
    

    你不能解释一下它的意义吗……我的意思是它一般都做什么?也许它确实知道 没有一个 一元值

    2 回复  |  直到 10 年前
        1
  •  2
  •   insan-e    10 年前

    你看到了吧 flatten 可以对包含可转换为的值的集合调用 GenTraversableOnce :

    def flatten[B](implicit asTraversable: A => GenTraversableOnce[B]): CC[B]
    

    自年起 Option companion object 存在到的隐式转换 Iterable ,它应该有资格 可迭代的 是的子类型 GenTraversableOnce(发电机可通过一次) ).

    它转换 选项 List ,其实现是显而易见的。。

    如果我错了,请纠正我,我对Scala的集合实现感到非常困惑。。。

        2
  •  2
  •   Michael Kopaniov    10 年前

    Option对象中定义了隐式方法:

    implicit def option2Iterable[A](xo: Option[A]): Iterable[A] = xo.toList
    

    并在返回Iterable之前检查对象是否为空:

    def toList: List[A] =
        if (isEmpty) List() else new ::(this.get, Nil)
    

    这意味着在None上应用option2Iterable时,我们将得到一个空列表。

    因此,这条线:

    b ++= asTraversable(xs).seq
    

    实际上是在None上执行时向b添加一个空seq,或者在Some中添加一个值为Some的列表。

    这就是为什么在展平输出中看不到None/Some对象,而只能看到Some对象的值。