ความแตกต่างระหว่างสิ่งนี้กับตัวเองในคำอธิบายประกอบประเภทตัวเอง?


137

ในวรรณกรรมต่างๆของ Scala ฉันเห็นคำอธิบายประกอบประเภทตัวเองโดยใช้ "this" และอื่น ๆ ที่ใช้ "self":

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

มีความแตกต่างอย่างแท้จริงระหว่างการใช้ "this" หรือ "self" หรือไม่? ชื่อที่คุณใช้มีความสำคัญหรือไม่? แค่นี้ก็ใช้ได้แล้ว?

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

คำตอบ:


182

ทั้งสามรูปแบบที่ถูกต้องและมีผลกระทบที่Bจะถือว่าเป็นชนิดของในชั้นเรียนthisA

สองตัวแปรแรก

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

แนะนำself(ตามลำดับfoo) เป็นชื่อแทนสำหรับในลักษณะthis Aสิ่งนี้มีประโยชน์สำหรับการเข้าถึงการthisอ้างอิงจากคลาสภายใน กล่าวคือคุณสามารถใช้selfแทนA.thisเมื่อเข้าถึงการthisอ้างอิงของลักษณะAจากคลาสที่ซ้อนอยู่ภายใน ตัวอย่าง:

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

ตัวแปรที่สาม

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

ไม่แนะนำนามแฝงสำหรับthis; เพียงแค่ตั้งค่าประเภทตนเอง


วิธีที่ฉันดูประเภทตัวเองคือลักษณะที่ประกาศตัวเองว่ารับประเภทบางประเภทและส่งคืนรหัสบล็อกเช่น foo: B => {... } แน่นอนว่าตอนนี้ curlies เหล่านั้นถูกละเว้น เป็นเรื่องน่าสนใจที่จะเห็นว่าคุณสามารถใช้ชื่อวัตถุแทน "this" ในขอบเขตใดก็ได้ในโค้ดแม้ว่า [สิ่งที่เราทำตลอดเวลาใน javascript]
Ustaman Sangat

4
@Martin Odersky เป็นไปได้ไหมที่จะเพิ่มข้อ จำกัด สำหรับสองลักษณะหรือมากกว่านั้นtrait A { self: B, C => ... }?
Dmitry Bespalov

13
@DmitryBespalov: ใช่คุณสามารถใช้withคำสำคัญในคำอธิบายประกอบการพิมพ์ด้วยตนเอง ตัวอย่างเช่นtrait A { self: B with C => ... }
Dave

1
btw คุณสามารถทำ_: B =>สำหรับกรณีที่ไม่ใช่นามแฝงเพื่อความเรียบง่าย
Creos

17

มีความแตกต่างที่thisมักจะอ้างถึงวัตถุที่กำหนดโดยเทมเพลตด้านในสุด

นิพจน์thisสามารถปรากฏในส่วนคำสั่งของเทมเพลตหรือชนิดผสม ย่อมาจากวัตถุที่ถูกกำหนดโดยแม่แบบด้านในสุดหรือประเภทสารประกอบที่ล้อมรอบการอ้างอิง ถ้าเป็นประเภทสารประกอบประเภทของthisสารประกอบนั้น ถ้าเป็นแม่แบบของชั้นหรือวัตถุที่มีชื่อความหมายง่ายๆCประเภทนี้เป็นเช่นเดียวกับประเภทของC this. (อ้างอิง Scala §6.5)

ดังนั้นหากคุณเรียกตัวเองfooว่าคุณยังคงสามารถเรียกมันว่าthis(เว้นแต่คุณจะอยู่ในเทมเพลตภายในซึ่งในกรณีนี้thisจะอ้างถึงวัตถุที่กำหนดโดยมัน - และเว้นแต่คุณจะไม่ให้ภายใน แม่แบบพิมพ์ชื่อเดียวกันเอง) แต่เห็นได้ชัดว่าไม่ใช่ในทางกลับกัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.