此类型与自我类型注释之间的区别?


134

在各种Scala文献中,我看到一些使用“ this”的自我类型注释,另一些使用“ self”的注释:

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

使用“ this”或“ self”之间有什么真正的区别?使用什么名字有关系吗?这一样有效吗?

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

Answers:


181

所有这三种形式都是有效的,并且具有B假定为thisin类中的类型的效果A

前两个变体

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

在trait中引入self(分别foo)作为别名。这对于从内部类访问引用很有用。即,您可以使用而不是从嵌套在其中的类访问特征的引用时使用。例:thisAthisselfA.thisthisA

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 => {...}。现在当然省去了那些冰壶。有趣的是,您可以在代码的任何作用域内使用对象名称代替“ this”,尽管[我们一直在使用javascript进行操作]
Ustaman Sangat 2013年

4
@Martin Odersky是否可以为两个或多个特征添加限制,例如trait A { self: B, C => ... }
德米特里·贝斯帕洛夫

13
@DmitryBespalov:是的,您可以with在自键入批注中使用关键字。例如trait A { self: B with C => ... }
Dave

顺便说一句,您也可以_: B =>为简单起见而对非别名情况进行处理
Creos

17

所不同的是,this始终引用最内层模板定义的对象。

该表达式this可以出现在模板或复合类型的语句部分中。它代表由包含引用的最里面的模板或化合物类型定义的对象。如果是复合类型,则该类型this为该复合类型。如果它是一个类或对象定义与简单名称的模板Ç,这样做的类型相同的类型Çthis。(Scala参考第6.5节)

因此,如果您调用self-type foo,您仍然可以将其称为this(除非,除非您在一个内部模板中,this否则在这种情况下,它将引用由它定义的对象–除非您不指定内部类型模板的自我类型具有相同的名称),但显然并非相反。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.