2012-05-09 18 views
5

ジェネリックの特性は、特定の基本クラスを継承し、コンパニオンオブジェクトとクラスそのもの。だから、クラスとそのコンパニオンオブジェクトを型パラメータとして受け取るジェネリックな特性

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

は、だから私は、以下のフランクからの溶液で行きましたが、私は私の最初のパズルを解決するために管理しました。この場合、解決策は少し醜いですが、私は完全性のためにここに含めます。

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は、コンパニオンオブジェクトのタイプのようです。

答えて

1

私は、型をBaseCrudの型に使用して、混在するクラスを指定することができます。詳しくは、linked questionを参照してください。あなたのコード内の問題の束があります

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) 
} 
+0

おかげで作品が、私は私のBaseModel [T]は、コードの他の部分のためのCustomerオブジェクトに混入する必要があります。しかし、私はBaseCrud [T]からコントローラにアクセスするために同じコードでこのテクニックを使用しました。 – gimo4000

6

..さんが次々にそれに取り組むみましょう:このTは、メソッドのスコープの元の型パラメータを上書きすること

  • def table[T](...ノート。あなたが本当に望んでいないものを、そうちょうどそれを省略して作るこのdef table(...
  • object Controller with BaseCrud {は、さらに2つのミスが含まれています
    1. それはextendsないwithなければなりません。後者は、すでにいくつかの基底クラス/形質から拡張した後にのみ使用されます。
    2. BaseCrud
    3. 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) 
} 
+0

ありがとうございました。私のコードの間違いをお詫びして申し訳ありませんが、そのほとんどはテストケースのために削除されました。私はコンパニオンオブジェクトとそのクラスの間に違いがあることを認識していましたが、型パラメータとして渡す方法はうまくいかなかった(非常に良い解決策ではありませんでした)。 – gimo4000

関連する問題