當前位置: 首頁>>編程示例 >>用法及示例精選 >>正文


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。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。