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

scala – Enrich-My-Library适用于所有Traversables

发布时间:2020-12-16 18:50:51 所属栏目:安全 来源:网络整理
导读:我试图弄清楚如何编写一个适用于任何Traversable [_]的函数交换函数,给定一个集合和交换索引.我想出了以下内容: def swap[A,CC % Traversable[A]](xs: CC,i: Int,j: Int): Traversable[A] = { xs.slice(0,i) ++ xs.slice(j,j+1) ++ xs.slice(i+1,j) ++ xs.s
我试图弄清楚如何编写一个适用于任何Traversable [_]的函数交换函数,给定一个集合和交换索引.我想出了以下内容:

def swap[A,CC <% Traversable[A]](xs: CC,i: Int,j: Int): Traversable[A] = {
  xs.slice(0,i) ++ 
    xs.slice(j,j+1) ++ 
    xs.slice(i+1,j) ++ 
    xs.slice(i,i+1) ++ 
    xs.slice(j+1,xs.size)
}

swap(List(1,2,3,4,5),4) // => List(5,1)

我想知道如何将它变成Traversable的隐式扩展,使我能够用List(1,5).swap(0,4)调用它.我能得到的最接近的是:

import language.implicitConversions
class RichTraversable[A,B <% Traversable[A]](xs: B) {
  def swap(i: Int,j: Int): Traversable[A] = {
    xs.slice(0,i) ++ 
      xs.slice(j,j+1) ++ 
      xs.slice(i+1,j) ++ 
      xs.slice(i,i+1) ++ 
      xs.slice(j+1,xs.size)
  }
} 
implicit def richTraversable[A,B <% Traversable[A]](ys: B)(implicit b: Traversable[A])
  = new RichTraversable[A,B](ys)

不幸的是,这不是它.调用列表(1,4)会导致以下错误:

error: No implicit view available from List[Int] => Traversable[A]

我觉得我必须遗漏一些东西,或者过度复杂化这个问题.有谁知道这应该如何构建?

注意:这纯粹是学术性的,不以任何方式在生产环境中使用.我正在努力更好地处理Scala的类型系统和界限.

解决方法

如果您使用的是Scala 2.10:

import scala.collection.generic.CanBuildFrom
import scala.collection.TraversableLike

implicit class TraversableWithSwap[A,Repr <: Traversable[A]](val xs: TraversableLike[A,Repr]) extends AnyVal {
  def swap[That](i: Int,j: Int)(implicit bf: CanBuildFrom[Repr,A,That]): That = {
    val builder = bf(xs.asInstanceOf[Repr])
    builder.sizeHint(xs)
    builder ++= xs.take(i)
    builder ++= xs.slice(j,j + 1)
    builder ++= xs.slice(i + 1,j)
    builder ++= xs.slice(i,i + 1)
    builder ++= xs.drop(j + 1)
    builder.result
  }
}

(AnyVal将其转换为值类,这意味着编译器会将其重写为静态函数,以避免在运行时实际执行包装.)

如果使用早期版本,请删除扩展AnyVal并使用隐式转换函数而不是隐式类:

implicit def toTraversableWithSwap[A,Repr <: Traversable[A]](xs: TraversableLike[A,Repr]) = new TraversableWithSwap(xs)

并使用它:

scala> Vector(1,5,6,7,8,9).swap(2,5)
res0: scala.collection.immutable.Vector[Int] = Vector(1,9)

请注意,为所有Traversable定义此函数实际上没有意义,因为某些可遍历(如Set,Map等)是无序的,因此交换两个元素是没有意义的.您可能实际上想要为所有Seq或其他东西定义它.

另外:我们也可以同意将其称为“增强我的库”吗?

(编辑:李大同)

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

    推荐文章
      热点阅读