[英]Create a companion object that mixes in a trait that defines a method which returns an object of the object's companion class
[英]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 {
包含兩個錯誤:
extends
不with
。 后者僅在您已從某些基類/特征擴展后使用。 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.