Różnica między tym a sobą w adnotacjach typu własnego?

134

W różnych literaturach Scala widzę adnotacje typu własnego używające „tego”, a inne używające „siebie”:

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

Czy jest jakaś prawdziwa różnica między używaniem „tego” a „ja”? Czy w ogóle ma znaczenie, jakiego imienia użyjesz? Czy to jest tak samo ważne?

trait A { foo: B => ... }
Zach
źródło

Odpowiedzi:

181

Wszystkie trzy formy są ważne i mają skutek Bprzyjęty jako typ thiszajęć A.

Pierwsze dwa warianty

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

Przedstaw self(odpowiednio foo) jako alias dla thiscechy in A. Jest to przydatne do uzyskiwania dostępu do thisodwołania z klasy wewnętrznej. To znaczy, możesz użyć selfzamiast A.thispodczas uzyskiwania dostępu do thisreferencji cechy Az klasy zagnieżdżonej w niej. Przykład:

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

Trzeci wariant,

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

nie wprowadza aliasu dla this; po prostu ustawia typ własny.

Martin Odersky
źródło
Sposób, w jaki patrzę na typ własny, polega na tym, że cecha zadeklarowała się jako przyjmująca określony typ i zwracająca blok kodu, np. Foo: B => {...}. Teraz te loki są oczywiście pomijane. Ciekawe jest to, że możesz użyć nazwy obiektu zamiast „this” w dowolnym zakresie w kodzie [coś, co robimy cały czas w javascript]
Ustaman Sangat
4
@Martin Odersky Czy można dodać ograniczenie dla dwóch lub więcej cech, na przykład trait A { self: B, C => ... }?
Dmitry Bespalov
13
@DmitryBespalov: Tak, możesz użyć withsłowa kluczowego w adnotacji do samodzielnego wpisywania. Na przykładtrait A { self: B with C => ... }
Dave
btw można też zrobić _: B =>na razie nie alias dla uproszczenia
Creos
17

Jest różnica w tym, że thiszawsze odnosi się do obiektu zdefiniowanego przez najbardziej wewnętrzny szablon.

Wyrażenie thismoże pojawić się w części instrukcji typu szablonu lub typu złożonego. Oznacza obiekt definiowany przez najbardziej wewnętrzny szablon lub typ złożony obejmujący odniesienie. Jeśli jest to typ złożony, typ thisjest tym typem złożonym. Jeśli jest to szablon z klasy lub obiektu definicji z nazwą prostą C , typ ten jest taki sam jak typ C . this. (Scala Ref. §6.5)

Tak więc, jeśli nazwiesz swój typ siebie foo, nadal możesz nazywać go jako this(chyba że, oczywiście, jesteś w szablonie wewnętrznym, w którym to przypadku thisbędziesz odnosić się do zdefiniowanego przez niego obiektu - i chyba że nie podasz wewnętrznego template samodzielnie wpisuje tę samą nazwę), ale oczywiście nie na odwrót.

Dębilski
źródło