我有以下扩展类,将扩展类添加myAppend到任何方法SeqLike。
implicit class WithAppend[A, R](s: SeqLike[A, R]) extends AnyVal {
def myAppend(i: A)(implicit cbf: CanBuildFrom[R, A, R]): R = s :+ i
}
Run Code Online (Sandbox Code Playgroud)
如何将该代码移植到Scala 2.13并保留类似的性能特征?如果扩展类可以保持AnyVal
我尝试过的几件事:
class Extends1[R, S <: IsSeq[R]](c: R, isSeq: S) {
def myAppend(a: isSeq.A): R = (isSeq(c) :+ a).asInstanceOf[R]
}
Run Code Online (Sandbox Code Playgroud)
但是asInstanceOf令人失望-它甚至安全吗?
我可以做:
class Extends3[S[_], A](c: SeqOps[A, S, S[A]]) {
def myAppend(a: A): S[A] = c :+ a
}
Run Code Online (Sandbox Code Playgroud)
但是现在我们被限于表单的集合,S[A]而Scala 2.12代码可以接受任何形式R。
我可以想出一个无需强制转换即可工作的方法签名和实现:
implicit class WithAppend[Repr](private val repr: Repr) extends AnyVal {
def myAppend[A0, C](a: A0)(
implicit
isSeq: IsSeq[Repr]{ type A = A0 },
b: BuildFrom[Repr, A0, C]
): C = b.fromSpecific(repr)(isSeq(repr) :+ a)
}
Run Code Online (Sandbox Code Playgroud)
很难保证其性能,但我怀疑它会比你以前的性能差很多。另一种选择是b.newBuilder(repr).addAll(isSeq(repr)).addOne(a).result()。
scala> List(1,2).myAppend(3)
res3: List[Int] = List(1, 2, 3)
scala> Vector(1,2).myAppend(3)
res4: scala.collection.immutable.Vector[Int] = Vector(1, 2, 3)
scala> "Strin".myAppend('g')
res5: String = String
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
162 次 |
| 最近记录: |