2010-08-06 23 views
9

Digamos que tiene los siguientes rasgos:tipo auto herencia en Scala

trait A 

trait B { this: A => } 

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

compilador de error: illegal inheritance; self-type C does not conform to B's selftype B with A
Como era de esperar si quitar los comentarios del tipo auto anotación, el compilador es feliz.

Creo que es bastante obvio por qué C también necesita este tipo de auto. Lo que no entiendo es por qué no puede "heredarlo" de A si el compilador ya puede darse cuenta de que es necesario?

Creo que podría reducir la verbosidad cuando use self-types con jerarquías complicadas, especialmente si mezcla un gran grupo de rasgos, cada uno de ellos tiene su propio tipo de auto-escritura.

Supongo que probablemente haya una buena razón para el comportamiento actual, simplemente no pude encontrar/averiguar de qué se trata.

Al principio pensé que podría estar relacionado con la linealización de mixin, pero me parece que no funciona aquí (incluso si tuviera más rasgos mezclados con tipos más complicados).

¿Causaría ambigüedades en algunos casos? Si es así, ¿por qué no puede funcionar cuando no hay ambigüedad?

¿O se relaciona con algunas dificultades en la correcta implementación de la misma?

Pude encontrar algunas discusiones sobre el tema (como self type is not inherited), pero en su mayoría solo indican el problema y concluyen que así es sin demasiadas explicaciones y/o una solución (si existe).

Respuesta

1
trait C extends B with A 

no es la única solución. También podría tener

trait AA extends A 
trait C extends B with AA 

Es decir, todo lo que hereda se acepta la interfaz de A. Si debe confiar en una implementación concreta, debería elegir un mixin; si la implementación depende del usuario o si tiene una buena razón para no especificar el mixin en el rasgo (por ejemplo, para relajar problemas de dependencia), lo haría un tipo propio.

+1

Creo que es claro para mí cuál es la diferencia entre mezclar en un rasgo o hacerlo uno mismo. Mi pregunta es: suponiendo que quiero los rasgos anteriores con el tipo de self y la mezcla tal como están y el compilador puede darse cuenta de que necesito (al menos) A como el tipo de letra de C por qué no puede "agregarlo" automáticamente. –

+0

Creo que sería indeseable en muchas ocasiones, ya que luego compilaría sin darle la oportunidad de especializar la clase. ¿Y qué hacer cuando 'A' no está disponible en el alcance actual? Creo que eso sería confuso y que la herencia y la mezcla deberían hacerse explícitas. Además, cuando quiera guardar el tipeo, podría definir un 'caracter CA extiende C con A' y usar eso. – Debilski

+1

Debilski, estás malentendiendo la pregunta. El OP quiere que "el rasgo C extienda B" sea equivalente a "el rasgo C extiende B {esto: A =>}", no a "el rasgo C extiende B con A". – Blaisorblade