Это потому, что параметры типа в Scala по умолчанию инвариантны, это означает, что:
Builder [Type1.type] не является подтипом Builder [MyType].
В этом блокеваш код, вам нужен Builder [MyType], и ни type1Builder, ни type2Builder не являются подтипами Builder [MyType]:
def test[T <: MyType](t:MyType): Unit = {
println(Builder.build(t))
}
Вы можете сделать параметр типа Builder ковариантным (Builder [+ A]), но затеми type1Builder, и type2Builder будут кандидатами для этого неявного, так что он снова потерпит неудачу.
Что вам нужно сделать, это использовать в вашем тестовом методе границу Context, а не верхнюю границу типа, как показано ниже:
def test[T : Builder](t: T): Unit = {
println(Builder.build(t))
}
Это означает, что тест получает тип T, который является членом класса типа Builder, и Type1, и Type2 являются членами класса типа Builder, поскольку есть Builder [Type1.type] и Builder [Type2.type] в неявной области видимости.
Если вы также хотите ограничить тестирование, чтобы его можно было вызывать только с реализациями MyType
, вы можете использовать как верхнюю границу типа, так и контекстную границу.:
def test[T <: MyType : Builder](t: T): Unit = {
println(Builder.build(t))
}
test(Type1) // building1
test(Type2) // building2