2012-04-18 12 views
8

Quiero anular el tipo abstracto en rasgo con <: y no con = (como la respuesta aquí Scala Upper Bounds : value is not a member of type parameter).El patrón de torta con tipo abstracto primordial no funciona con Upper Type Bounds

Quiero usar patrón de pastel, pero esto no funciona, no entiendo por qué?

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

trait Cake { 
    type T 
} 

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

bien, este ejemplo de ejecución, pero en mi caso de uso real Quiero anular tipo con <: y no con = .Se parece imposible acceder a la función t, ¿por qué?

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

devolverá un error value ping is not a member of S.this.T

Respuesta

15

Es un defecto de sistema de tipos de Scala. Al determinar los miembros en un mixin, Scala usa dos reglas: Primero, el hormigón siempre anula el resumen. En segundo lugar, si dos miembros son tanto concretos como abstractos, gana el que aparece más tarde en el orden de linealización.

Además, el tipo de auto de un rasgo

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

se ve aumentada de forma implícita a

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

de modo que las definiciones en el rasgo S se puede acceder dentro de S. En su caso, el rasgo S se ve como:

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

Ahora, siempre que T sea concreto, esto está bien porque anula la ab abstrae T en Cake. Pero si T es abstracto, el de Cake aparece más tarde en el orden de linealización y gana. Y esa T no tiene un límite superior, por lo que ningún miembro hace ping. Una forma de solucionar este problema es cambiar el orden de linealización por escrito:

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

Sería más limpia si Scala tenía una regla diferente que dice que todas las limitaciones de los miembros de tipo abstracto se fusionan en el mixin, en lugar de escoger una único miembro según el orden de linealización. Ese es un cambio que queremos considerar en el futuro, pero debemos ser cuidadosos con la compatibilidad con versiones anteriores.

Cuestiones relacionadas