コードのスニペットは次のとおりです。
class Foo[A] {
def foo[B](param: SomeClass[B]) {
//
}
}
さて、内部foo
では、どのようにすればよいですか:
1)BがAと同じタイプであるかどうかを確認しますか?
2)BがAのサブタイプであるかどうかを確認しますか?
コードのスニペットは次のとおりです。
class Foo[A] {
def foo[B](param: SomeClass[B]) {
//
}
}
さて、内部foo
では、どのようにすればよいですか:
1)BがAと同じタイプであるかどうかを確認しますか?
2)BがAのサブタイプであるかどうかを確認しますか?
ちなみに、一般化された型制約は実際には必要ありません。
class Foo[A] {
def foo_subParam[B <: A](param: SomeClass[B]) {...}
def foo_supParam[B >: A](param: SomeClass[B]) {...}
def foo_eqParam[B >: A <: A](param: SomeClass[B]) {...}
def foo_subMyType[Dummy >: MyType <: A] {...}
def foo_supMyType[Dummy >: A <: MyType] {...}
def foo_eqMyType[Dummy1 >: MyType <: A, Dummy2 >: A <: MyType] {...}
}
実際、私はこの方法を好みます。これは、型推論をわずかに改善し、無関係なランタイムデータが使用されないことを保証するためです。
<:<
サブタイプチェックと=:=
同じタイプチェックには、暗黙のタイプエビデンスが必要です。この質問の回答を参照してください。
1)BがAと同じタイプかどうかを確認しますか?
class Foo[A] {
def foo(param: SomeClass[A]) = ???
}
// or
class Foo[A] {
def foo[B](param: SomeClass[B])(implicit ev: A =:= B) = ???
}
2)BがAのサブタイプであるかどうかを確認しますか?
class Foo[A] {
def foo[B <: A](param: SomeClass[B]) = ???
}
// or
class Foo[A] {
def foo[B](param: SomeClass[B])(implicit ev: B <:< A) = ???
}
あなたの場合、一般化された型制約(すなわち、 )は必要あり ません。これらは、メソッドではなく、他の場所で定義されている型パラメーターに制約を追加する必要がある場合に必要です。=:=
<:<
例:確実にするためA
にString
:
class Foo[A] {
def regularMethod = ???
def stringSpecificMethod(implicit ev: A =:= String) = ???
}
ここでは、一般化された型制約なしで型制約を強制することはできません。