scala – 作为集合的“包装器”类的案例类.那么map / foldLeft /
我尝试做的是提出一个案例类,我可以在模式匹配中使用它只有一个字段,例如不可变的集合.此外,我想使用map,foldLeft等函数,这些函数应该传递给集合.我试过它,如下所示:
case class foo(s:Set[String]) extends Iterable[String] { override def iterator = s.iterator } 现在如果我试图利用例如map函数,我得到一个类型错误: var bar = foo(Set() + "test1" + "test2") bar = bar.map(x => x) found : Iterable[String] required: foo bar = bar.map(x => x) ^ 类型错误完全正常(在我的理解中).但是,我想知道如何为集合实现一个包装器案例类,以便可以调用map,foldLeft等,并仍然接收案例类的对象.是否需要覆盖所有这些功能还是有其他方法吗? 编辑 我倾向于接受为我工作的RégisJean-Gilles的解决方案.然而,谷歌搜索几个小时后,我发现另一个有趣的Scala特征名为SetProxy.我找不到任何琐碎的例子,所以我不确定这个特性是否符合我的要求: >提出自定义类型,即与Set不同的类型 我的第一个想法是扩展Set但我的自定义类型Foo已经扩展了另一个类.因此,第二个想法是混合特性Iterable和IterableLike.现在我对特性SetProxy感兴趣,这让我想到哪种方式是“最好的”.你有什么想法和经历? 自从我三天前开始学习Scala以来,我们非常感谢任何指针! 解决方法
你是对的.仅仅继承自mpartel所示的IterableLike将使某些方法的返回类型更精确(例如filter,它将返回Foo),但对于其他如flatMap的map,你需要提供一个隐含的适当的CanBuildFrom. import collection.IterableLike import collection.generic.CanBuildFrom import collection.mutable.Builder case class Foo( s:Set[String] ) extends Iterable[String] with IterableLike[String,Foo] { override def iterator = s.iterator override protected[this] def newBuilder: scala.collection.mutable.Builder[String,Foo] = new Foo.FooBuilder def +(elem: String ): Foo = new Foo( s + elem ) } object Foo { val empty: Foo = Foo( Set.empty[String] ) def apply( elems: String* ) = new Foo( elems.toSet ) class FooBuilder extends Builder[String,Foo] { protected var elems: Foo = empty def +=(x: String): this.type = { elems = elems + x; this } def clear() { elems = empty } def result: Foo = elems } implicit def canBuildFrom[T]: CanBuildFrom[Foo,String,Foo] = new CanBuildFrom[Foo,Foo] { def apply(from: Foo) = apply() def apply() = new FooBuilder } } 在repl中进行一些测试: scala> var bar = Foo(Set() + "test1" + "test2") bar: Foo = (test1,test2) scala> bar = bar.map(x => x) // compiles just fine because map now returns Foo bar: Foo = (test1,test2) (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |