加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

如何在Scala中创建带有有界类型参数的自定义Seq?

发布时间:2020-12-16 18:37:15 所属栏目:安全 来源:网络整理
导读:考虑以下工作自定义Seq: class MySeq[B](val s: Seq[B]) extends Seq[B]with GenericTraversableTemplate[B,MySeq]with SeqLike[B,MySeq[B]] { override def companion = MySeq def iterator = s.iterator def apply(i: Int) = s(i) def length = s.length
考虑以下工作自定义Seq:

class MySeq[B](val s: Seq[B]) 
extends Seq[B]
with GenericTraversableTemplate[B,MySeq]
with SeqLike[B,MySeq[B]] {
  override def companion = MySeq

  def iterator = s.iterator

  def apply(i: Int) = s(i)

  def length = s.length

  override def toString = s map { _.toString } mkString("n")
}
object MySeq extends SeqFactory[MySeq] {
  implicit def canBuildFrom[B]: CanBuildFrom[Coll,B,MySeq[B]] =
       new GenericCanBuildFrom[B]
  def newBuilder[B] = new ListBuffer[B] mapResult (x => new MySeq(x.toSeq))
}

我想对类型参数B施加一个限制.换句话说,我想要这样的东西(不工作):

class MyA

class MySeq[+B <: MyA](val s: Seq[B]) 
extends Seq[B]
with GenericTraversableTemplate[B,MySeq[B]] {
  override def companion = MySeq  // Type Mismatch Here

  def iterator = s.iterator

  def apply(i: Int) = s(i)

  def length = s.length

  override def toString = s map { _.toString } mkString("n")
}
object MySeq extends SeqFactory[MySeq] {
  implicit def canBuildFrom[B]: CanBuildFrom[Coll,MySeq[B]] =
       new GenericCanBuildFrom[B]
  // Type Mismatch in the line below
  def newBuilder[B] = new ListBuffer[B] mapResult (x => new MySeq(x.toSeq))
}

但是我在指定的行中出现以下类型不匹配错误:

inferred type arguments [B] do not conform to 
class MySeq's type parameter bounds [+B <: MyA] 
Main.scala  line 49

type mismatch;  
found   : countvotes.structures.MySeq.type  
required: scala.collection.generic.GenericCompanion[Seq]    
Main.scala  line 36

type mismatch;  
found   : MySeq[B(in class MySeq)]  
required: MySeq[B(in method newBuilder)]    
Main.scala  line 49

type mismatch;  
found   : scala.collection.immutable.Seq[B(in method newBuilder)]  
required: Seq[B(in class MySeq)]    
Main.scala  line 49

我试图通过向CanBuildFrom和newBuilder的类型参数添加边界来解决这个问题,但后来我得到了其他错误消息.

如何创建绑定了类型参数的自定义Seq?

解决方法

我没有收到第26行的错误:

override def companion = MySeq

也许还有其他因素导致了这一点

无论如何,问题是你不能拥有GenericCompanion [MySeq](SeqFactory的超类型).原因是GenericCompanion [Coll]意味着你可以为任何A构造一个Coll [A](参见newBuilder的签名).你也不能拥有MySeq [A]<:GenericTraversableTemplate [A,MySeq],因为genericBuilder是不可能的.这是有道理的; MySeq实际上不是一个“通用集合”,因为它希望它的元素都是MyA. 解决方案是让MySeq [B]<:GenericTraversableTemplate [B,Seq],(免费扩展Seq).然后你有两个伴侣选择.它可以是Seq的默认值,也可以是s.companion.在第一种情况下,((as:MySeq [A]):Seq [A]).map(...)将产生一个List(在运行时;在编译时它只是一个通用的Seq).在第二个中,它将取决于as.s是什么(再次,在运行时;编译时只会看到一个Seq).但是,你可以保留扩展的SetLike. 然后,您需要提供自定义CanBuildFrom:MySeq.canBuildFrom [A&lt ;: MyA]:CanBuildFrom [MySeq [A],A,MySeq [A]],并定义MySeq#newBuilder.

class MySeq[+B <: MyA](val s: Seq[B]) 
  extends Seq[B]
  with SeqLike[B,MySeq[B]]
{
  override def iterator = s.iterator
  override def apply(i: Int) = s(i)
  override def length = s.length

  override def toString = s.map(_.toString).mkString("n")

  override def companion = s.companion
  protected[this] override def newBuilder: mutable.Builder[B,MySeq[B]] = new mutable.Builder[B,MySeq[B]] {
    private[this] val base = s.genericBuilder[B]
    override def +=(elem: B) = { base += elem; this }
    override def clear() = base.clear()
    override def result() = new MySeq[B](base.result())
  }
}

object MySeq {
  implicit def canBuildFrom[A <: MyA]: CanBuildFrom[MySeq[_],MySeq[A]] = ???
}

val list = List(new MyA,new MyA,new MyA)
val vect = list.toVector
val mLst = new MySeq(list)
val mVec = new MySeq(vect)
{
  val res = mLst.filter(_.hashCode != list.head.hashCode)
  implicitly[res.type <:< MySeq[MyA]]
}
{
  val res = (mVec: Seq[MyA]).map(identity)
  assert(res.isInstanceOf[Vector[_]])
}
{
  val res = (mLst: Seq[MyA]).map(identity)
  assert(res.isInstanceOf[List[_]])
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读