Załóżmy, że mam dwie klasy: Input
i Output
, które są przeznaczone do połączenia ze sobą. Output
wytwarza wartości pewnego rodzaju, a Input
je konsumuje.Dlaczego Scala nie może podać parametru typu w tym przykładzie?
class Input[T] {
var output: Option[Output[_ <: T]] = None
}
class Output[T] {
var input: Option[Input[_ >: T]] = None
}
Jest w porządku, jeśli Input
i Output
para nie działają na tym samym rodzaju wartości, o ile typ parametru Input
jest supertypem parametru Output
typu. Zauważ, że parametr type w obu klasach jest niezmienny; w wersjach rzeczywistych jest używany zarówno w pozycjach współwystępujących, jak i przeciwstawnych.
Mam connect
metodę gdzie indziej który ustanawia związek między Input
/Output
pary:
def connect[T](output: Output[T], input: Input[_ >: T]) = {
output.input = Some(input)
input.output = Some(output)
}
Gdybym wywołać tę metodę, jak poniżej, pojawia się błąd typu:
val out = new Output[String]
val in = new Input[AnyRef]
connect(out, in)
Błąd:
test.scala:17: error: type mismatch;
found : Output[String]
required: Output[AnyRef]
connect(out, in)
^
Mogę rozwiązać ten problem, wypisując parametr type (w tym przypadku napisałbym connect[String]
, ale myślę, że kompilator powinien być w stanie to dla mnie wyliczyć. Jak mogę zmienić metodę connect
tak, aby parametr typu został wywnioskowany automatycznie?
Edit: Na razie zrobiłem connect
metoda Output
więc robi parametr typu automatycznie. Ma to również dodatkową zaletę, że mogę używać notacji infix out connect in
, ale projekt wydaje się trochę niezręczny.
Nadal interesuje mnie, dlaczego kompilator wykazuje takie zachowanie. Czuję, że powinien być w stanie wywnioskować parametr typu. Czy to rzeczywiście działa zgodnie z określonymi?
czy masz na myśli "nie dzialaj * przy * tej samej wartości" –
Czy próbowałeś zadać to pytanie na liście mailingowej Scala? – GClaramunt