¿Diferencia entre esto y self en anotaciones de self-type?

134

En varias publicaciones de Scala veo algunas anotaciones de auto-tipo que usan "this" y otras que usan "self":

trait A { this: B => ... }
trait A { self: B => ... }

¿Hay alguna diferencia real entre usar "this" o "self"? ¿Importa en absoluto qué nombre usas? ¿Es esto tan válido?

trait A { foo: B => ... }
Zach
fuente

Respuestas:

181

Las tres formas son válidas y tienen el efecto que Bse supone como el tipo de thisclase A.

Las dos primeras variantes

trait A { self: B => ... }
trait A { foo: B => ... }

introducir self(respectivamente,foo ) como un alias para thisen rasgo A. Esto es útil para acceder a la thisreferencia desde una clase interna. Es decir, podría usarlo en selflugar de A.thisacceder a la thisreferencia del rasgo Adesde una clase anidada en él. Ejemplo:

class MyFrame extends JFrame { frame =>    
  getContentPane().add( new JButton( "Hide" ) {
    addActionListener( new ActionListener {
      def actionPerformed( e: ActionEvent ) {
        // this.setVisible( false ) --> shadowed by JButton!
        frame.setVisible( false )
      }
    })
  })
}

La tercera variante,

trait A { this: B => ... }

no introduce un alias para this; solo establece el auto tipo.

Martin Odersky
fuente
La forma en que miro el tipo automático es que el rasgo se declaró a sí mismo como que toma un cierto tipo y devuelve el bloque de código, por ejemplo, foo: B => {...}. Ahora, por supuesto, esos curlies se omiten. Sin embargo, es interesante ver que puedes usar el nombre del objeto en lugar de "esto" dentro de cualquier ámbito del código [algo que hacemos todo el tiempo en JavaScript]
Ustaman Sangat
44
@ Martin Odersky ¿Es posible agregar restricciones para dos o más rasgos, algo así trait A { self: B, C => ... }?
Dmitry Bespalov
13
@DmitryBespalov: Sí, puede usar la withpalabra clave en la anotación autoescrita . Por ejemplotrait A { self: B with C => ... }
Dave
por cierto también se puede hacer _: B =>para el caso no alias para simplicidad
Creos
17

Hay una diferencia en que thissiempre se refiere al objeto definido por la plantilla más interna.

La expresión thispuede aparecer en la parte de la declaración de una plantilla o tipo compuesto. Representa el objeto definido por la plantilla más interna o el tipo compuesto que encierra la referencia. Si este es un tipo compuesto, el tipo de thises ese tipo compuesto. Si se trata de una plantilla de una definición de clase o un objeto con el nombre sencillo C , el tipo de esto es el mismo que el tipo de C . this. (Ref. Scala §6.5)

Entonces, si llama a su auto-tipo foo, aún podría referirse a él como this(a menos, por supuesto, que esté en una plantilla interna en cuyo caso thisse referirá al objeto definido por él, y a menos que no le dé el interno auto-teclea el mismo nombre) pero obviamente no al revés.

Debilski
fuente