简体   繁体   English

如何通过使用 Scala 中的类型在特征中使用 Object

[英]How to use an Object in a trait by using its type in Scala

I was trying to implement some Model - Row implementation similar that Rails (Activerecord) in Scala.我试图实现一些 Model - 行实现类似于 Scala 中的 Rails (Activerecord)。 I simply trying to do this;我只是想这样做;

trait Model[A]:
  def query = "model has this good stuff I want to use in RowData"

trait RowData[B <: Model[B]]:
  def query = B.query

case class Person(name: String, age: Int) extends RowData[Person]

object Person extends Model[Person]

Person("onur", 38).query // I wan't to use like this

I'm getting Not found: B on RowData trait.我得到 Not found: B on RowData特征。 Because Model[A] is an object I supposed that I can use it as is.因为Model[A]是 object 我想我可以按原样使用它。

You can try in here: https://scastie.scala-lang.org/U3MOJhFXSS2O8fanY5aIpg你可以在这里试试: https://scastie.scala-lang.org/U3MOJhFXSS2O8fanY5aIpg

trait RowData[B <: Model[B]]:
  def query = B.query

This is not supported because (among other reasons) the query method might not exist.这不受支持,因为(除其他原因外) query方法可能不存在。

The problem is that the type of the companion object is not related to the type of the class.问题是配套 object 的类型与 class 的类型无关。 So the fact that B is a subclass of Model[B] says nothing about the type of the companion object of B .因此, BModel[B]的子类这一事实并没有说明B的伴侣 object 的类型。 And specifically, it does not require the companion object of B to be a subclass of Model[B] and therefore it is not required to have the appropriate query method.具体来说,它不需要B的伴侣 object 是Model[B]的子类,因此不需要具有适当的query方法。

The other problem is that this does not compile:另一个问题是这不能编译:

trait RowData[B <: Model[B]]:
  def query = B.query

case class Person(name: String, age: Int) extends RowData[Person]

The RowData trait requires that Person is a subclass of Model[Person] but Person does not inherit from Model[Person] RowData特征要求PersonModel[Person]的子类,但Person不继承自Model[Person]

You either need to have Person inherit from Model and provide the appropriate query method, or look at using a type class for this problem.您要么需要PersonModel继承并提供适当的query方法,要么查看使用 class 类型来解决此问题。

It seems the requirement is to use companion object's method, but the issue with this solution is that,似乎要求是使用伴随对象的方法,但这个解决方案的问题是,

trait RowData[B <: Model[B]]:
  def query = B.query

Because B is supposed to be an Object, it cannot be passed as a type in [] .因为B应该是 Object,所以它不能作为[]中的类型传递。 You need to pass it as an Object in a parenthesis () , like this您需要在括号()中将其作为 Object 传递,如下所示

trait Model[A]:
  def query = "model has this good stuff I want to use in RowData"

trait RowData(B: Model[_]):
  def query = B.query

case class Person(name: String, age: Int) extends RowData(Person)

object Person extends Model[Person]

Person("onur", 38).query

However, this is not an ideal solution either, because B is not enforced to be the companion object you pass for the row data class.但是,这也不是一个理想的解决方案,因为 B 并未强制成为您为行数据 class 传递的伴随 object。 In Scala, we commonly use Context Bound to enforce this, like this :在 Scala 中,我们通常使用 上下文绑定来强制执行此操作,如下所示

trait Model[A]:
  def query = "model has this good stuff I want to use in RowData"

trait RowData[B : Model]:
  def query = summon[Model[B]].query

case class Person(name: String, age: Int) extends RowData[Person]

given Person: Model[Person] with {} //Implement custom query method here

Person("onur", 38).query

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM