Unterschied zwischen diesem und dem Selbst in Annotationen vom Typ Selbst?

134

In verschiedenen Scala-Literaturen sehe ich einige Anmerkungen vom Typ "this" und andere, die "self" verwenden:

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

Gibt es einen wirklichen Unterschied zwischen "diesem" oder "Selbst"? Ist es überhaupt wichtig, welchen Namen Sie verwenden? Ist das genauso gültig?

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

Antworten:

181

Alle drei Formen sind gültig und haben den Effekt, der Bals Typ thisin der Klasse angenommen wird A.

Die ersten beiden Varianten

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

Einführung self(jeweils foo) als Alias für thisin trait A. Dies ist nützlich, um thisvon einer inneren Klasse aus auf die Referenz zuzugreifen . Dh Sie könnten dann verwenden, selfanstatt A.thisauf die thisReferenz des Merkmals Avon einer darin verschachtelten Klasse aus zuzugreifen . Beispiel:

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 )
      }
    })
  })
}

Die dritte Variante,

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

führt keinen Alias ​​für ein this; es setzt nur den Selbsttyp.

Martin Odersky
quelle
Ich betrachte den Selbsttyp so, dass sich das Merkmal als ein bestimmter Typ deklariert und den Codeblock zurückgibt, z. B. foo: B => {...}. Jetzt werden diese Locken natürlich weggelassen. Es ist interessant zu sehen, dass Sie den Objektnamen anstelle von "this" in einem beliebigen Bereich des Codes verwenden können [etwas, das wir die ganze Zeit in Javascript tun]
Ustaman Sangat
4
@Martin Odersky Ist es möglich, eine Einschränkung für zwei oder mehr Merkmale hinzuzufügen, so etwas wie trait A { self: B, C => ... }?
Dmitry Bespalov
13
@DmitryBespalov: Ja, Sie können das withSchlüsselwort in der selbsteingabenden Anmerkung verwenden. Zum Beispieltrait A { self: B with C => ... }
Dave
Übrigens können Sie _: B =>der Einfachheit halber auch für den Nicht-Alias-Fall tun
Creos
17

Es gibt einen Unterschied, der sich thisimmer auf das Objekt bezieht, das durch die innerste Vorlage definiert ist.

Der Ausdruck thiskann im Anweisungsteil einer Vorlage oder eines zusammengesetzten Typs erscheinen. Es steht für das Objekt, das durch die innerste Vorlage oder den zusammengesetzten Typ definiert wird, der die Referenz einschließt. Wenn dies ein zusammengesetzter Typ ist, ist der Typ thisdieser zusammengesetzte Typ. Wenn es sich um eine Vorlage einer Klasse oder eines Objektdefinition mit einfacher Name ist C , ist die Art der diese die gleiche wie die Art von C . this. (Scala Ref. §6.5)

Wenn Sie also Ihren Selbsttyp aufrufen foo, können Sie ihn immer noch als bezeichnen this(es sei denn, Sie befinden sich in einer inneren Vorlage. In diesem Fall thisbezieht er sich auf das von ihm definierte Objekt - und es sei denn, Sie geben den inneren nicht an Die Vorlage gibt den gleichen Namen selbst ein), aber offensichtlich nicht umgekehrt.

Debilski
quelle