2016-04-11 14 views
-1

は、コードの構造です:パラメータ化されたメソッドを参照する方法は?ここ

trait Foo[T <: Foo[_]] { 
    def makeACopy[T](attr01_p: Option[String], ...): T 
    ... 
} 

case class Bar extend Foo[Bar] { 
    def makeACopy[Bar](attr01_p: Option[String], ...): org.myapp.domain.model.Bar = copy(attr01 = attr01_p, ...) 
    ... 
} 

今、別のクラスのメソッドは、メソッドmakeACopyを参照する必要があります。

class Qux(...){ 
    ... 
    private def myMethod[T <: Foo](id: Long, getter: Long => Option[T], ...): Option[T] = { 
    val b = getter(id) 
    b match { 
     case Some(bar) => bar.makeACopy[T](...) // <== It isn't right 
     case None => ... 
    } 
} 

私はfooとのIntelliJ IDEAのサブタイプがライン文句を言わないので、私はすでに、パラメータを指定するもののmakeACopyメソッドを呼び出すための準拠エラーを取得:

value makeACopy is not a member of type parameter T 

はなぜ?そしてそれを解決する方法は?

また、私はなぜ、バーにmakeACopyの返されたデータ型のフルパスを持たなければならないのか分かりません。そうしないと、IDEは返された型の不一致を訴えるでしょう。

+1

あなたは 'Foo'sと' Bar'sで失われなければならない:)あなたがパッケージ名を指定する必要が理由をその戻り値の型は、おそらく複数の 'Bar'があることを示唆しています。また、 '' Foo'はパラメータ化が必要なので、 '' T [:Foo] 'はコンパイルすべきではありません。その行にエラーがない場合、範囲内に別の' Foo'があります。 – Dima

+0

あなたのご意見ありがとうございます。それは私の場合ではないようです。私はその名前のクラスのうちの1つしか見つけることができません。 – TeeKai

+0

何でも...どんな場合でも、 'Foo [T <:Foo]'は有効なコードではありません。intellijは混乱しているかもしれません。あなたは前進する前にそれを修正する必要があります。 – Dima

答えて

1

あなたがfooのサブクラスとしてT命名分離型のパラメータを定義し、それらの一つだけだ:

trait Foo[T <: Foo[_]] { // defining T once 
    // that's another definition of a whole different T: 
    def makeACopy[T](attr01_p: Option[String], ...): T 
    ... 
} 

トレイト(またはクラス)内で定義されたメソッドの型パラメータをTその後

trait Foo[T <: Foo[_]] { 
    // T used as return value is the one defined in trait: 
    def makeACopy(attr01_p: Option[String], ...): T 
    ... 
} 

あなたが/オーバーライドmakeACopyを呼び出すどこ、あなたが必要としない、:あなたはおそらくこれを変更したいので、再びTを宣言するべきではありませんあなたはFoo /拡張を作成したときのタイプを指定するには、すでに例えば、でした:

case class Bar extend Foo[Bar] { 
    def makeACopy(attr01_p: Option[String], ...): Bar = copy(attr01 = attr01_p, ...) 
    ... 
} 
関連する問題