如何解决为什么 Scala Option.tapEach 返回 Iterable,而不是 Option?
Option.tapEach
的 scaladoc 声明“返回:与此相同的逻辑集合”,正如对以 tap
& {{1 命名的操作的预期一样}}。但是,它不返回 foreach
而是返回由 Option
支持的 Iterable
:
List
(已针对 Scala 2.13.5 和 3.0.0-RC1 验证)
是否有充分的理由返回 scala> import scala.util.chaining._
scala> Option(5).tap(_.foreach(_ => ()))
val res0: Option[Int] = Some(5)
scala> Option(5).tapEach(_ => ())
val res1: Iterable[Int] = List(5)
而不是 Iterable
,或者这只是被忽略了(最终可能会被修复)?
解决方法
似乎 Option
是否被认为是一个完整的集合有点像在 Make Option extend IterableOnce #8038 上的讨论所表明的那样。我认为相关的 comment 是
所以它绝对可以是一个 IterableOnce
因为你可以得到一个迭代器
零到一的元素。但它不能是 Iterable
因为你
不抛出就无法实现 fromSpecific(c: IterableOnce[A]): K
离开数据。
然而 tapEach
在其定义中使用了 fromSpecific
override def tapEach[U](f: A => U): C = fromSpecific(new View.Map(this,{ (a: A) => f(a); a })
因此要记住的关键是 Option
,因为 Scala 2.13 是 IterableOnce
但不是完整的 Iterable
。 IterableOnce
与 Iterable
相比较小,因此如果需要来自 Iterable
的功能,则根据 docs
此成员是通过从 Option[A]
的隐式转换添加的
到 Iterable[A]
由 option2Iterable
中的方法 scala.Option
执行。
就是
option2iterable(Option(5)).tapEach(_ => ())
因此是 Iterable[Int]
返回类型。
还要考虑以下note
这里的许多方法与上面的方法重复 可遍历的层次结构,但它们被复制是有原因的: 在某些情况下,隐式转换往往会留下一个 Iterable 可以保留一个选项的地方。
所以贡献者必须在 Option 中烘焙一个专门的版本来保留类型,或者我们可以提供我们自己专门的扩展实现,比如
scala> implicit class OptionTapOps[A](v: Option[A]) {
| def tapEach[B](f: A => B): Option[A] = { v.foreach(f); v }
| }
class OptionTapOps
scala> Option(5).tapEach(_ => ())
val res11: Option[Int] = Some(5)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。