2012-04-18 6 views
8

Chcę zastąpić typ abstrakcyjny cechą z <:, a nie z = (jak tutaj odpowiedź Scala Upper Bounds : value is not a member of type parameter).Wzór ciasta z nadpisującym typem abstrakcyjnym nie działa z górnymi granicami typów

Chcę użyć wzoru ciasta, ale to nie działa, nie rozumiem dlaczego?

trait A { 
    def ping = println("ping") 
} 

trait Cake { 
    type T 
} 

trait S { this: Cake => 
    type T = A 
    def t: T 
    t.ping 
} 

OK, przykład ten bieg, ale w moim przypadku użycia rzeczywistym chcę zastąpić typ z <: a nie z = .To wydaje się niemożliwe, aby uzyskać dostęp do funkcji t, dlaczego?

trait S { this: Cake => 
    type T <: A 
    def t: T 
    t.ping 
} 

zwróci błąd value ping is not a member of S.this.T

Odpowiedz

15

Jest to wada systemu typu Scala. Podczas określania członków w mixinie, Scala stosuje dwie reguły: Po pierwsze, konkretne zawsze zastępuje abstrakcje. Po drugie, jeśli dwóch członków jest zarówno konkretnych, jak i obu abstrakcyjnych, wygrywa ten, który pojawia się później w kolejności linearyzacji.

Ponadto rodzaj samodostosowania cechy

trait S { this: C => ... } 

jest niejawnie zwiększona do

trait S { this: S with C => ... } 

tak, że definicje w cechę S mogą być dostępne w ciągu S. W twoim przypadku, cechą S jest postrzegany jako:

trait S { this: S with Cake => 
    type T = A 
    def t: T 
    t.ping 
} 

Teraz, dopóki T jest konkretne, jest w porządku, ponieważ jest nadrzędne w stosunku do ab stract T in Cake. Ale jeśli T jest abstrakcyjne, to w Cake zasiada później w kolejności linearyzacji i wygrywa. I że T nie ma górnej granicy, więc żaden członek ping. Jednym ze sposobów, aby naprawić to, aby zmienić kolejność linearyzacji pisząc:

trait S { this: Cake with S => 
    type T <: A 
    def t: T 
    t.ping 
} 

byłoby czystsze jeśli Scala miał inny przepis, który mówi, że wszystkie ograniczenia abstrakcyjnych elementów typu są scalane w wstawek, zamiast Picking pojedynczy element zgodnie z porządkiem linearyzacji. To jest zmiana, którą chcemy rozważyć w przyszłości, ale musimy zachować ostrożność przy kompatybilności wstecznej.

Powiązane problemy