Perbedaan antara this dan self dalam anotasi tipe diri?

137

Dalam berbagai literatur Scala, saya melihat beberapa anotasi tipe diri menggunakan "ini" dan lainnya menggunakan "diri":

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

Apakah ada perbedaan nyata antara menggunakan "ini" atau "diri"? Apakah penting nama apa yang Anda gunakan? Apakah ini sama validnya?

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

Jawaban:

182

Ketiga bentuk tersebut valid, dan memiliki efek yang Bdianggap sebagai jenis thisdalam kelas A.

Dua varian pertama

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

perkenalkan self(masing-masing, foo) sebagai alias untuk thisin trait A. Ini berguna untuk mengakses thisreferensi dari kelas dalam. Yaitu, Anda kemudian dapat menggunakan selfalih-alih A.thissaat mengakses thisreferensi sifat Adari kelas yang bersarang di dalamnya. Contoh:

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

Varian ketiga,

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

tidak memperkenalkan alias untuk this; itu hanya mengatur tipe diri.

Martin Odersky
sumber
Cara saya melihat tipe diri adalah bahwa sifat tersebut menyatakan dirinya sebagai mengambil tipe tertentu dan mengembalikan blok kode misalnya foo: B => {...}. Sekarang rambut ikal itu tentu saja dihilangkan. Sangat menarik untuk melihat bahwa Anda dapat menggunakan nama objek alih-alih "ini" di dalam lingkup apa pun dalam kode meskipun [sesuatu yang kami lakukan sepanjang waktu di javascript]
Ustaman Sangat
4
@ Martin Odersky Apakah mungkin menambahkan pembatasan untuk dua atau lebih sifat, seperti trait A { self: B, C => ... }?
Dmitry Bespalov
13
@DmitryBespalov: Ya, Anda dapat menggunakan withkata kunci dalam anotasi pengetikan sendiri. Misalnyatrait A { self: B with C => ... }
Dave
1
btw juga dapat Anda lakukan _: B =>untuk
kasing
17

Ada perbedaan yang thisselalu mengacu pada objek yang didefinisikan oleh template terdalam.

Ekspresi thisdapat muncul di bagian pernyataan dari templat atau tipe gabungan. Ini singkatan dari objek yang ditentukan oleh templat terdalam atau tipe gabungan yang melampirkan referensi. Jika ini adalah tipe gabungan, tipe tersebut thisadalah tipe gabungan. Jika template dari definisi kelas atau objek dengan nama sederhana C , jenis ini adalah sama dengan jenis C . this. (Scala Ref. §6.5)

Jadi, jika Anda menyebut tipe-diri fooAnda, Anda masih bisa merujuknya sebagai this(kecuali, tentu saja, Anda berada di templat bagian dalam yang dalam hal ini thisakan merujuk ke objek yang ditentukan olehnya - dan kecuali Anda tidak memberikan bagian dalam template mengetik sendiri nama yang sama) tetapi jelas bukan sebaliknya.

Debilski
sumber