当前位置: 首页>>代码示例 >>用法及示例精选 >>正文


Scala generic.IsIterable用法及代码示例


用法 一

trait IsIterable[Repr] extends IsIterableOnce[Repr]

定义扩展方法时可用于避免代码重复的特征,这些扩展方法应该适用于现有的 Scala 集合(即扩展 Iterable 的类型)以及可以转换为 Scala 的其他(可能是用户定义的)类型集合类型.这个特性使得处理 Scala 集合和可以统一隐式转换为集合类型的类型成为可能。例如,可以提供适用于集合类型和 String 的扩展方法( String 不扩展 Iterable ,但可以转换为 Iterable )

IsIterable 提供三个成员:

1. 类型成员 A ,表示目标的元素类型 Iterable[A] 1. 类型成员 C ,表示保留集合元素类型的转换操作返回的类型 1. 方法 apply ,它提供一种在我们希望添加扩展方法的类型之间进行转换的方法,ReprIterableOps[A, Iterable, C]

用法

必须提供IsIterable 作为隐式转换的隐式参数类型。它的用法如下所示。我们在以下示例中的目标是为任何扩展或可以转换为 Iterable 的类型提供通用扩展方法 mapReduce。在我们的示例中,这包括 String

  import scala.collection.{Iterable, IterableOps}
  import scala.collection.generic.IsIterable

  class ExtensionMethods[Repr, I <: IsIterable[Repr]](coll: Repr, it: I) {
    def mapReduce[B](mapper: it.A => B)(reducer: (B, B) => B): B = {
      val iter = it(coll).iterator
      var res = mapper(iter.next())
      while (iter.hasNext)
        res = reducer(res, mapper(iter.next()))
      res
    }
  }

  implicit def withExtensions[Repr](coll: Repr)(implicit it: IsIterable[Repr]): ExtensionMethods[Repr, it.type] =
    new ExtensionMethods(coll, it)

// See it in action!
List(1, 2, 3).mapReduce(_ * 2)(_ + _) // res0: Int = 12
"Yeah, well, you know, that's just, like, your opinion, man.".mapReduce(x => 1)(_ + _) // res1: Int = 59

在这里,我们首先创建一个类ExtensionMethods,其中包含我们的mapReduce 扩展方法。

请注意,ExtensionMethods 采用 Repr 类型的构造函数参数 coll ,其中 Repr 表示(通常)集合类型,以及 IsIterable[Repr] 子类型的参数 it 。该方法的主体首先将coll 参数转换为IterableOps,以便在其上调用iterator 方法。其余的实现很简单。

withExtensions 隐式转换使mapReduce 操作可用于任何类型Repr,它存在隐式IsIterable[Repr] 实例。请注意我们如何通过使用 it.type 单例类型而不是更广泛的 IsIterable[Repr] 类型来跟踪隐式 it 参数的精确类型。我们这样做是为了不丢失it 参数的类型成员AC 携带的信息。

mapReduce 方法在某些类型上调用它不是它的成员时,会触发隐式搜索。因为隐式转换 withExtensions 是通用的,所以只要可以找到类型为 IsIterable[Repr] 的隐式值,就会应用它。鉴于 IsIterable 伴随对象包含返回类型为 IsIterable 的值的隐式成员,通常会满足此要求,并且将上一段中说明的交互链设置为行动。 (请参阅 IsIterable 伴随对象,其中包含可用隐式的精确规范。)

注意: 目前,由于类型推断的限制,无法将隐式转换和类与扩展方法组合成一个隐式类。

为新类型实现IsIterable

必须简单地提供特定于新类型的IsIterable 类型的隐式值,或者返回特定于新类型的IsIterable 实例的隐式转换。

下面是 IsIterable 特征的实现示例,其中 Repr 类型为 Range

implicit val rangeRepr: IsIterable[Range] { type A = Int; type C = IndexedSeq[Int] } =
 new IsIterable[Range] {
   type A = Int
   type C = IndexedSeq[Int]
   def apply(coll: Range): IterableOps[Int, IndexedSeq, IndexedSeq[Int]] = coll
 }

(注意在实践中IsIterable[Range]实例已经由标准库提供,它被定义为IsSeq[Range]实例)

伴生:

object

源码:

IsIterable.scala

用法 二

object IsIterable extends IsIterableLowPriority

伴生:

class

源码:

IsIterable.scala

相关用法


注:本文由纯净天空筛选整理自scala-lang.org大神的英文原创作品 generic.IsIterable。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。