scala – 为协变集合添加`到[Col [_]]`方法
发布时间:2020-12-16 18:55:23 所属栏目:安全 来源:网络整理
导读:我正在实现一个数据结构.虽然它没有直接混合 Scala的任何标准集合特性,但我希望包含to [Col [_]]方法,在给定构建器工厂的情况下,该方法可以生成标准的Scala集合. 现在假设这一点,从GenTraversableOnce复制: trait Foo[+A] { def to[Col[_]](implicit cbf: C
我正在实现一个数据结构.虽然它没有直接混合
Scala的任何标准集合特性,但我希望包含to [Col [_]]方法,在给定构建器工厂的情况下,该方法可以生成标准的Scala集合.
现在假设这一点,从GenTraversableOnce复制: trait Foo[+A] { def to[Col[_]](implicit cbf: CanBuildFrom[Nothing,A,Col[A]]): Col[A] } 这失败并出现错误:协变类型A出现在不变位置. 那 这看起来像一个肮脏的把戏.如果typer正常拒绝这种情况,那么如何安全地使用uncheckedVariance关闭? 解决方法
方差检查是类型检查的一个非常重要的部分,跳过它可能很容易导致运行时类型错误.在这里,我可以通过打印来演示填充了无效运行时值的类型.尽管如此,我还是无法使用类型转换异常使其崩溃.
import collection.generic.CanBuildFrom import collection.mutable.Builder import scala.annotation.unchecked.uncheckedVariance trait Foo[+A] { def toCol[Col[_]](implicit cbf: CanBuildFrom[Nothing,Col[A @uncheckedVariance]]): Col[A @uncheckedVariance] } object NoStrings extends Foo[String] { override def toCol[Col[_]](implicit cbf: CanBuildFrom[Nothing,String,Col[String]]): Col[String] = { val res : Col[String] = cbf().result println("Printing a Col[String]: ") println(res) res } } case class ExactlyOne[T](t : T) implicit def buildExactlyOne = new CanBuildFrom[Nothing,Any,ExactlyOne[Any]] { def apply() = new Builder[Any,ExactlyOne[Any]] { def result = ExactlyOne({}) def clear = {} def +=(x : Any) = this } def apply(n : Nothing) = n } val noStrings : Foo[Any] = NoStrings noStrings.toCol[ExactlyOne] 这里println(res)与res:Col [String]打印ExactlyOne(()).但是,ExactlyOne(())没有Col [String]类型,表明类型错误. 为了在尊重方差规则的同时解决问题,我们可以将不变代码移出特征,只保留协变部分,同时使用隐式转换从协变特征转换为不变辅助类: import collection.generic.CanBuildFrom trait Foo[+A] { def to[R](implicit cbf: CanBuildFrom[Nothing,R]): R } class EnrichedFoo[A](foo : Foo[A]) { def toCol[Col[_]](implicit cbf: CanBuildFrom[Nothing,Col[A]]): Col[A] = foo.to[Col[A]] } implicit def enrich[A](foo : Foo[A]) = new EnrichedFoo(foo) case class Bar[A](elem: A) extends Foo[A] { def to[R](implicit cbf: CanBuildFrom[Nothing,R]): R = { val b = cbf() b += elem b.result() } } val bar1 = Bar(3) println(bar1.toCol[Vector]) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |