W wariancie Scala można zdefiniować wariancję z operatorami wariancji, takimi jak + i - na typowym argumencie typu. Na przykład typ List
jest kowariancyjny w bibliotece standardowej.Podczas korzystania z notacji kowariancji lub ogólnych ograniczeń w Scali
class List[+A]
Więc funkcja z listy kowariantna można zdefiniować tak:
def foo[A](list : List[A])
także wariancji może być emulowane z granic rodzajowych. Tak więc możemy również napisać ten
def foo[A](list : List[_:< A])
oczywiście to nie ma sensu, ponieważ list
jest już kowariantna. Ale tę samą sztuczkę można zrobić dla typów, które nie są kowariantne. (jak Stack
). Oczywiście można również tworzyć nowe typy ze stosu (dziedziczenie agregacji), który jest kowariantny.
więc moje pytania:
- Kiedy należy używać granic rodzajowych dla wariancji? A kiedy powinniśmy stworzyć nowy typ kowariancyjny?
- Czy ogólne ograniczenia są przydatne tylko w przypadku wariancji, czy mogą zadeklarować więcej (koncepcje językowe).
- Jeśli są one użyteczne tylko dla wariancji, czy granice to tylko dla zgodności z Javą?
thx z góry :)
Podwojenie tego pytania - wariancja jest najcięższą częścią Scali i właściwie nie rozumiem tego całkiem dobrze. "Blah-bla covariant bla pojawił się w pozycji contravariant blah-blah": p – Jeriho
Zrozumiałem wariancję, gdy spojrzałem na definicje niektórych cech funkcji (funkcja 1, funkcja 2 itd.) Cechy funkcji są kowariantne na typie wyjściowym i contravariant na typach wejściowych (parametr). Na przykład funkcja typu "Any => Unit" może być użyta wszędzie tam, gdzie oczekiwana jest funkcja typu 'String => Unit', ponieważ funkcja' Any => Unit' może przyjmować ciąg znaków jako dane wejściowe (ponieważ może to brać wszystko jako dane wejściowe.) Z tego powodu typy parametrów metody są "przeciwstawną pozycją". –