首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >supertype中的Scala复制方法

supertype中的Scala复制方法
EN

Stack Overflow用户
提问于 2013-10-17 01:14:08
回答 1查看 189关注 0票数 1

我有一个抽象类(这是一个类似的例子) Printer,它打印提供的参数,除非它不能传递一个过滤器。Printer是逆变异的w.r.t.其泛型类型为T

代码语言:javascript
复制
class Printer[-T] {
  val filters: Seq[Function2[T => Boolean]]

  def print(t: T): Unit {
    if (filters.forall(_(t))) doPrint(t)
  }
  def doPrint(t: T): Unit
}

我现在有20个Printer的子类--一个用于String、Ints等。因为Printer是反变体,所以filters必须是一个val。但是,如果我想要一个Printer方法添加一个过滤器,它需要是不可变的。

代码语言:javascript
复制
def addFilter[TT <: T](t: TT): Printer[TT]

不幸的是,我现在需要在我的20个子类中实现这个方法。有办法绕过这件事吗?

更新:另外,在addFilter中,我不知道如何返回子类而不是超类Printer。例如,如果我在一个addFilter上调用StringPrinter,那么理想情况下,我会得到StringPrinter类型。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-10-17 03:24:30

THe下面的代码与您编写Printer的方式有点不同,但可能会实现您的意图。请注意,这种编写类代码的方式可以更好地分离关注点:您可以定义过滤器和打印实现( doPrint参数),而不管它们是如何使用的:

代码语言:javascript
复制
case class Printer[T](val filters: List[Function1[T, Boolean]], val doPrint: T => Unit) {
  def print(t: T): Unit = {
    if (filters.forall(_(t))) doPrint(t)
  }

  def addFilter[TT <: T](f: TT => Boolean): Printer[TT] = copy(f :: filters)
}

请注意,我不需要在这里指定对比,不确定这是否会成为您的问题。

要使用该类,不需要子类,只需将适当的参数传递到构造函数(实际上,为case类免费提供的配套apply工厂方法)-例如:

代码语言:javascript
复制
case class Foo(x: Int)
val fooChk1: Foo => Boolean = (f: Foo) => f.x != 1
val fooPrinter1 = Printer(fooChk1 :: Nil, (f: Foo) => println(s"Foo: x = ${f.x}"))

val fooChk3: Foo => Boolean = (f: Foo) => f.x != 3
val fooPrinter2 = fooPrinter1.addFilter(fooChk3)

val foo3 = Foo(3)
fooPrinter1.print(foo3) // Prints 'Foo: x = 3'
fooPrinter3.print(foo3) // Prints nothing

在这里也有一个相当大的使用范围,这两个参数都适用于Print (例如。将构造函数更改为(val filters: List[Function1[T, Boolean]])(implicit val doPrint: T => Unit)),并针对特定的Print[X]变体。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19416634

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档