使用泛型强制 Scala 特征的类型

Enforcing the type of a Scala trait using a generic

本质上,我正在尝试执行以下操作:

trait Foo[T] extends T {
  def json: Writes[T]
  def bar: String = {
    Json.toJson[T](this)(json).toString
  }
}

我希望编译器强制使用特征 Foo 的任何 class 都是 T 类型。不幸的是,'extends T' 无效。现在,我能做的最好的是:

trait Foo[T] extends T {
  def json: Writes[T]
  def bar: String = {
    Json.toJson(this.asInstanceOf[T])(json).toString
  }
}

但显然,编译器没有强制执行任何操作。反正有没有办法实现我想要的?

您可以使用 self type 来要求扩展 Foo[T] 的任何 class 也是 T:

的实例
import play.api.libs.json._

trait Foo[T] { self: T =>
  def json: Writes[T]
  def bar: String = Json.toJson[T](self)(json).toString
}

您可以使用任何您想要的名称来代替 self(这只是一个通用约定)。