Ваша декларация уже работает как положено, т.е. вы ограничиваете тип T
, а также Key
и Value
.Однако, как вы написали, scala будет жаловаться, если вы выдадите что-то вроде
scala> class Foo[T <: OtherT, Key[T], Value[T]]
defined class Foo
scala> new Foo[SpecialOtherT, Key[SpecialOtherT], Value[SpecialOtherT]]
<console>:13: error: Key[SpecialOtherT] takes no type parameters, expected: one
new Foo[SpecialOtherT, Key[SpecialOtherT], Value[SpecialOtherT]]
, поскольку типы Key
и Value
уже указаны в вашей предыдущей декларации.Следовательно, это будет работать
scala> new Foo[SpecialOtherT, Key, Value]
res20: Foo[SpecialOtherT,Key,Value] = Foo@3dc6a6fd
, что, вероятно, не так, как вы хотите.Вы можете сделать это следующим образом
scala> class Foo[T <: OtherT, K <: Key[T], V <: Value[T]]
defined class Foo
scala> new Foo[SpecialOtherT, Key[SpecialOtherT], Value[SpecialOtherT]]
res21: Foo[SpecialOtherT,Key[SpecialOtherT],Value[SpecialOtherT]] = Foo@7110506e
В нижней строке, поскольку типы Key
и Value
зависят исключительно от T
, несколько избыточно иметь всю эту избыточную информацию при работе сFoo
.Так почему бы не использовать внутреннее объявление типа следующим образом:
class Foo[T <: OtherT] {
type K = Key[T]
type V = Value[T]
}
Тогда у вас будет доступ к типам K
и V
из класса, но вам не нужно будет вводить его каждый раз при созданииновый ответ:
scala> new Foo[SpecialOtherT]
res23: Foo[SpecialOtherT] = Foo@17055e90
scala> new Foo[Int]
<console>:11: error: ...