在Scala蛋糕模式中键入错误

时间:2015-03-24 19:58:35

标签: scala design-patterns types

我有以下蛋糕模式:

// The framework
trait Frame[R] {
  def renderer:ReadRender[R]
  trait ReadRender[R] {      // <<<--- error
    def say[T](src:R) : T
  }
}

// A specific implementation
trait StringFrame extends Frame[String] {
  def renderer = new StringReadRender()
  class StringReadRender() extends ReadRender[String] {
    def say[T](src:String) : T = {
      println("Say: "+src)
      null.asInstanceOf[T]  // placeholder--actual work here in real code
    }
  }
}

// Wiring it up
trait SJ[R] {
  this : Frame[R] =>
    def foo[T](me:R) = {
      println("In foo")
      renderer.say[T](me)  
    }
}

case class Greg() extends SJ[String] with StringFrame

使用默认编译器设置,这会编译干净并且似乎有效。如果我启用-Xlint,我会在上面标记的行上收到此错误:

type parameter R defined in trait ReadRender shadows type R defined in trait ReadRenderFrame. You may want to rename your type parameter, or possibly remove it.

此模式是为JSON解析器设计的,允许使用mixin特性进行注入,支持不同类型的源数据 - 字符串default,但可以是字节流或Map。

我担心它会在-Xlint审查开始时抱怨 - 这让我想知道似乎在没有-Xlint的情况下工作是否真的很安全,或者我只需要是更具体的某种方式?

1 个答案:

答案 0 :(得分:2)

您对Frame[R]的定义目前等同于以下内容:

trait Frame[R] {
  def renderer:ReadRender[R]
  trait ReadRender[R1] {      // Defining a new type parameter
    def say[T](src:R1) : T
  }
}

所以linter抱怨说,ReadRender[R]的类型参数被称为Frame[R]的类型参数。根据定义,它们在提供的代码中实际上始终相同:def renderer:ReadRender[R]。因此,您可以完全丢弃ReadRender的类型参数,并使用Frame的类型参数代替它:

// The framework
trait Frame[R] {
  def renderer:ReadRender
  trait ReadRender {
    def say[T](src:R) : T     // R is provided by Frame[R]
  }
}

// A specific implementation
trait StringFrame extends Frame[String] {        // Setting R to String
  def renderer = new StringReadRender()
  class StringReadRender() extends ReadRender {  // R is equal to String here
    def say[T](src:String) : T = {
      println("Say: "+src)
      null.asInstanceOf[T]  // placeholder--actual work here in real code
    }
  }
}