Scala 在self类型注释中,它和self之间有什么区别?

Scala 在self类型注释中,它和self之间有什么区别?,scala,Scala,在各种Scala文献中,我看到一些使用此选项的自类型注释,还有一些使用自类型注释: trait A { this: B => ... } trait A { self: B => ... } 使用这个或自我之间有什么真正的区别吗?你用什么名字重要吗?这是否同样有效 trait A { foo: B => ... } 不同之处在于,它始终引用最内层模板定义的对象 该表达式可以出现在模板或复合类型的语句部分。它表示由包含引用的最内层模板或复合类型定义的对象。如果这是复合类型,则

在各种Scala文献中,我看到一些使用此选项的自类型注释,还有一些使用自类型注释:

trait A { this: B => ... }
trait A { self: B => ... }
使用这个或自我之间有什么真正的区别吗?你用什么名字重要吗?这是否同样有效

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

不同之处在于,它始终引用最内层模板定义的对象

该表达式可以出现在模板或复合类型的语句部分。它表示由包含引用的最内层模板或复合类型定义的对象。如果这是复合类型,则此类型就是该复合类型。如果它是具有简单名称C的类或对象定义的模板,则其类型与C的类型相同。Scala参考§6.5


因此,如果你称自己的类型为foo,你仍然可以这样称呼它,当然,除非你在一个内部模板中,在这种情况下,它将引用它定义的对象——除非你没有给内部模板的自我类型起相同的名称,但显然不是相反的名称。

所有三种形式都是有效的,其影响是B被假定为A类中的类型

前两个变体

trait A { self: B => ... }
trait A { foo: B => ... }
分别介绍self,foo作为trait A中的别名。这对于从内部类访问this引用非常有用。也就是说,当从嵌套在其中的类访问特征A的this引用时,可以使用self而不是A.this。例如:

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 => ... }

不为此引入别名;它只是设置self类型。

我看待self类型的方式是,trait声明自己接受某个类型并返回代码块,例如foo:B=>{…}。现在这些卷发当然被省略了。有趣的是,您可以在代码中的任何范围内使用对象名而不是此名称,尽管[我们在javascript中一直在做的事情]@Martin Odersky是否可以为两个或多个特征添加限制,比如特征A{self:B,C=>…}?@DmitryBespalov:Yes,可以在自键入批注中使用with关键字。例如,trait A{self:B with C=>…}顺便说一句,为了简单起见,您还可以对非别名的情况执行u:B=>