implicitly generic functions conversion annotation scala inheritance traits self-type

conversion - scala generic functions



Lo que es más Scala idiomático: rasgo TraitA extiende TraitB o trait TraitA{self: TraitB=>} (1)

Aparte del aspecto de herencia, hay una diferencia entre las siguientes plantillas de clase:

1| trait TraitA extends TraitB 2| trait TraitA { self: TraitB => }

Me gustaría dividir las responsabilidades entre TraitA y TraitB pero el primero no puede funcionar sin el segundo.

¿Cómo expresarías esta intención? Para mi solución [2] sería el enfoque más natural. Sin embargo, no quiero poner la carga de que los implementadores se mezclen con lo que se debe mezclar de todos modos.


Mi preferencia es generalmente [1] porque, como usted dice, el implementador no tiene la obligación de mezclarse en (un subtipo de) TraitB . Quizás [2] es preferible si, por alguna razón, es deseable no heredar las implementaciones concretas en TraitB y obligar al implementador a elegir entre los subtipos de TraitB . Aún así, [1] es igual de flexible.

Tiendo a usar [2] solo cuando es necesario, como cuando el tipo no es una clase o rasgo conocido,

// Here, Matrix cannot extend type parameter Repr trait Matrix[+Repr <: Matrix[Repr]] { self: Repr => ... }

Actualizar. Aquí hay otra diferencia menor,

trait B trait A { self: B => } def g(ab: A): B = ab // Type mismatch: found A, required B

Sus un poco molesto una restricción opcional para no poder usar A como B , aunque el tipo esté incorporado.