GenericTraversableTemplate::flatten。它有什么魔力?
GenericTraversableTemplate::flatten. What kind of magic does it do?
我想了解 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)
哇。它看起来像一些奇迹。 flatten
方法如何知道我们不应该将 None
添加到结果集合中。它的实现根本不明显:
def flatten[B](implicit asTraversable: A => /*<:<!!!*/ GenTraversableOnce[B]): CC[B] = {
val b = genericBuilder[B]
for (xs <- sequential)
b ++= asTraversable(xs).seq
b.result()
}
您不能解释一下它的含义吗...我的意思是它通常有什么作用?也许它确实知道 None
是一个 单值 并使用它的一些 "monadic" 方法。但这只是猜测。
Flatten 方法隐式接收一个方法,该方法能够采用 A(在我们的例子中是选项)并将其转换为 GenTraversableOnce。
选项对象中定义了一个隐式方法:
implicit def option2Iterable[A](xo: Option[A]): Iterable[A] = xo.toList
并且 toList 在返回 Iterable 之前检查对象是否为空:
def toList: List[A] =
if (isEmpty) List() else new ::(this.get, Nil)
意味着在 None 上应用 option2Iterable 时我们将得到一个空列表。
所以行:
b ++= asTraversable(xs).seq
实际上是在 None 上执行时向 b 添加一个空序列,或者在 a Some 的情况下向具有 Some 值的列表添加一个列表。
这就是为什么在展平输出中看不到 None / Some 对象,而只能看到 Some 对象的值的原因。
您看到 flatten
可以在包含可转换为 GenTraversableOnce
的值的集合上调用:
def flatten[B](implicit asTraversable: A => GenTraversableOnce[B]): CC[B]
因为在 Option
companion object 中存在到 Iterable
的隐式转换,它应该有资格成为 flatten
-ed(Iterable
是GenTraversableOnce
).
它将Option
转换为List
,其实现是显而易见的..
如果我错了请纠正我,我对 Scala 的集合实现感到不知所措...
我想了解 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)
哇。它看起来像一些奇迹。 flatten
方法如何知道我们不应该将 None
添加到结果集合中。它的实现根本不明显:
def flatten[B](implicit asTraversable: A => /*<:<!!!*/ GenTraversableOnce[B]): CC[B] = {
val b = genericBuilder[B]
for (xs <- sequential)
b ++= asTraversable(xs).seq
b.result()
}
您不能解释一下它的含义吗...我的意思是它通常有什么作用?也许它确实知道 None
是一个 单值 并使用它的一些 "monadic" 方法。但这只是猜测。
Flatten 方法隐式接收一个方法,该方法能够采用 A(在我们的例子中是选项)并将其转换为 GenTraversableOnce。
选项对象中定义了一个隐式方法:
implicit def option2Iterable[A](xo: Option[A]): Iterable[A] = xo.toList
并且 toList 在返回 Iterable 之前检查对象是否为空:
def toList: List[A] =
if (isEmpty) List() else new ::(this.get, Nil)
意味着在 None 上应用 option2Iterable 时我们将得到一个空列表。
所以行:
b ++= asTraversable(xs).seq
实际上是在 None 上执行时向 b 添加一个空序列,或者在 a Some 的情况下向具有 Some 值的列表添加一个列表。
这就是为什么在展平输出中看不到 None / Some 对象,而只能看到 Some 对象的值的原因。
您看到 flatten
可以在包含可转换为 GenTraversableOnce
的值的集合上调用:
def flatten[B](implicit asTraversable: A => GenTraversableOnce[B]): CC[B]
因为在 Option
companion object 中存在到 Iterable
的隐式转换,它应该有资格成为 flatten
-ed(Iterable
是GenTraversableOnce
).
它将Option
转换为List
,其实现是显而易见的..
如果我错了请纠正我,我对 Scala 的集合实现感到不知所措...