2010-08-06 13 views
9

Say I mają następujące cechy:typ Własna dziedziczenie w Scala

trait A 

trait B { this: A => } 

trait C extends B // { this: A => } 

Compiler błąd: illegal inheritance; self-type C does not conform to B's selftype B with A
Jak oczekiwano, gdybym odkomentuj zaworem adnotacji, kompilator jest szczęśliwy.

Myślę, że to całkiem oczywiste, dlaczego C również potrzebuje tego typu siebie. Czego nie rozumiem, dlaczego nie może go "odziedziczyć" z A, skoro kompilator mógł już zorientować się, że jest potrzebny?

Myślę, że może zmniejszyć szczegółowość, gdy użyjesz własnego typu ze skomplikowanymi hierarchiami, szczególnie jeśli mieszkasz w dużą grupę cech, z których każda ma swój własny typ.

Chyba prawdopodobnie istnieje dobry powód obecnego zachowania, po prostu nie mogłem znaleźć/dowiedzieć się, co to jest.

Początkowo myślałem, że może to być związane z linearyzacją mixin, ale wydaje mi się, że nie gra tutaj (nawet gdybym miał więcej cech mieszanych z bardziej skomplikowanymi typami siebie).

Czy może to powodować niejednoznaczności w niektórych przypadkach? Jeśli tak, dlaczego nie może działać, gdy nie ma dwuznaczności?

Czy jest to związane z pewnymi trudnościami we właściwym jej wdrożeniu?

Mogę znaleźć kilka dyskusji na ten temat (np. self type is not inherited), ale najczęściej po prostu określają problem i stwierdzają, że tak jest bez zbytniego wyjaśnienia i/lub rozwiązania (jeśli istnieje).

Odpowiedz

1

to nie jedyne rozwiązanie. Oznacza to, że akceptowane jest wszystko, co dziedziczy interfejs A. Jeśli musisz polegać na konkretnej implementacji, wybrałbyś mixin; jeśli implementacja jest zależna od użytkownika lub masz dobry powód, dla którego nie chcesz określać miksu w funkcji (na przykład w celu poluzowania problemów z zależnościami), zrobiłbyś to jako własny typ.

+1

Myślę, że dla mnie jest jasne, jaka jest różnica pomiędzy miksowaniem w cechach lub sprawiają, że jest to typ własny. Moje pytanie brzmi: zakładając, że chcę poprzednich cech z własnym typem i mieszaniem takim, jaki jest i kompilator może zorientować się, że potrzebuję (przynajmniej) A jako własny typ C, dlaczego nie może automatycznie "dodać" go? –

+0

Myślę, że byłoby to niepożądane przy wielu okazjach, ponieważ wtedy kompilował by się bez możliwości specjalizacji klasy. Co należy zrobić, gdy "A" nie jest dostępne w bieżącym zakresie? Sądzę, że byłoby to mylące i że należy wyraźnie określić dziedziczenie i mieszanie. Ponadto, jeśli chcesz zapisać wpisywanie, możesz zdefiniować 'cechę CA rozszerzającą C z A' i użyć tej. – Debilski

+1

Debilski, nie rozumiesz pytania. OP chce, aby "cecha C rozszerza B" była równoważna "cecha C rozszerza B {to: A =>}", a nie "cecha C rozszerza B o A". – Blaisorblade