首页 文章

Scala Collection CanBuildFrom

提问于
浏览
2

在Scala 2.10.2中,我试图通过滚动我自己的一些简单集合来了解有关集合层次结构的更多信息 .

下面是表示整数序列的玩具类的源代码 .

import scala.collection.SeqLike
import scala.collection.mutable.Builder
import scala.collection.generic.CanBuildFrom

object IntSeq
{
    def apply( ints : Int* ) : IntSeq = new IntSeq( ints )

    protected def newBuilder( iterable : Iterable[Int] ) : Builder[Int,IntSeq] = new Builder[Int,IntSeq]
    {
        var init = scala.collection.mutable.ArrayBuffer( iterable.toSeq:_* )
        def +=( elem : Int ) : this.type = { init += elem; this } 
        def result() : IntSeq = new IntSeq( init ) 
        def clear() : Unit = init = scala.collection.mutable.ArrayBuffer[Int]()
    }

    implicit def canBuildFrom : CanBuildFrom[Iterable[Int],Int,IntSeq] = new CanBuildFrom[Iterable[Int],Int,IntSeq]
    {
        def apply() : Builder[Int,IntSeq]= newBuilder( Seq() )
        def apply( from : Iterable[Int] ) : Builder[Int,IntSeq] = newBuilder( from )
    }
}

class IntSeq( seq : Seq[Int] )
    extends Seq[Int]
    with SeqLike[Int,Seq[Int]]
{
    def sumSquared() = seq.map( i => i * i ).sum

    // SeqLike interface
    def iterator : Iterator[Int] = seq.iterator

    def apply( idx : Int ) : Int = seq( idx )

    def length : Int = seq.length
}

我遇到的问题如下:在summary section of the page "The Architecture of Scala Collections"中,第4点说通过在伴随对象中提供隐式 canBuildFrommap 和类似函数将返回此类的实例 . 但是,这不会发生:

scala> IntSeq( ( 1 to 10 ):_* ).filter( _ % 2 == 0 )
res0: Seq[Int] = List(2, 4, 6, 8, 10)

任何人都能解释为什么会这样吗?

2 回答

  • 0

    看看过滤器方法返回什么 . 它从TraversableLike返回Repr类型 . 这与SeqLike中的第二个类型参数的类型相同 . 在你的情况下,它是Seq [Int] . 一切都按预期工作 . 如果你想获得IntSeq类型:

    class IntSeq( seq : Seq[Int] )
        extends Seq[Int]
        with SeqLike[Int,IntSeq]
    
  • 4

    filterSeqLike[A, Repr] 上,与许多类似的方法一样,返回 Repr 类型的值 . 但是,您使您的类扩展 SeqLike[Int, Seq[Int]] . 如果希望类上的操作返回 IntSeq 类型的值,则应扩展 SeqLike[Int, IntSeq] .

相关问题