簡體   English   中英

通用特征取一個類,它的伴隨對象作為類型參數

[英]generic trait taking a class and it's companion object as a type parameter

所以我希望將一個通用特征作為一個類型參數,一個具有從特定基類繼承的伴隨對象的類,並引用伴隨對象和類本身。 所以,

abstract class BaseModel[T] {
  def all: Seq[T]
}

case class Customer(email: String, password: String)

object Customer extends BaseModel[Customer]

// This trait is my issue
trait BaseCrud[T] { 
  def table[T](f: T => String): String = {
    T.all.map(f _).mkString("")
  }
}

object Controller with BaseCrud {
  def foo = table(_.email)
}

我有一些解決方案,這個特性更接近,但我把它提煉下來,這樣你就可以看到我想要做的事情。

謝謝

UPDATE

所以我選擇了Frank下面的解決方案,但我確實設法解決了我最初的難題。 雖然,在這種情況下,解決方案有點難看,但為了完整起見,我會將其包含在這里。

abstract class BaseModel[T] {
  def all: Seq[T] = Seq()
}

case class Customer(email: String, password: String)

object Customer extends BaseModel[Customer]

trait BaseCrud[T, U <: BaseModel[T]] { 
  def table(f: T => String)(implicit obj: U): String = {
    obj.all.map(f(_)).mkString("")
  }
}

object Controller extends BaseCrud[Customer, Customer.type] {
  implicit val model = Customer
  def foo = table(_.email)
}

因此,類型參數更改為BaseCrud,並將隱式添加到BaseCrud.table並在Controller.model中實現。 我也解決了所有錯別字。 我覺得有趣的是Customer.type似乎是伴侶對象的類型。

你的代碼中有很多問題......讓我們一個接一個地解決它:

  • def table[T](...請注意,這個T覆蓋方法范圍的原始類型參數。不是你想要的,所以只需省略它並制作這個def table(...
  • object Controller with BaseCrud {包含兩個錯誤:
    1. 它必須是extendswith 后者僅在您已從某些基類/特征擴展后使用。
    2. BaseCrud需要你必須在這里指定的類型參數,所以類似於BaseCrud[Customer]
  • 最后,回答你的實際問題: 類型參數T和伴隨對象之間存在巨大差異。 它們本質上是不同的東西,因此您無法通過T.something訪問伴隨對象。 相反,您需要以某種其他方式在特征中提供伴隨對象,例如作為抽象字段。

這是我認為你想做的一個版本:

abstract class BaseModel[T] {
  def all: Seq[T]
}

case class Customer(email: String, password: String)

object Customer extends BaseModel[Customer] {
  def all = List[Customer]() // have to define this
}

trait BaseCrud[T] {
  val companion : BaseModel[T]
  def table(f: T => String): String = {
    companion.all.map(f).mkString("")
  }
}

object Controller extends BaseCrud[Customer] {
  val companion = Customer
  def foo = table(_.email)
}

我認為,您可以在BaseCrud特征中使用scala self類型來指定它應該混合的類。有關詳細信息,請參閱鏈接的問題

trait BaseCrud[T] {
  self: BaseModel[T] =>
  def table(f: T => String): String =
    all.map(f).mkString("")
}

object Controller extends BaseModel[Customer] with BaseCrud[Customer]{
  def foo = table(_.email)
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM