1. self的场景
self不是关键字,可以用除了this以外的任何名字命名,在这个场景下,self和this是等价的
class A{
self =>
val x = 2
def selfEqThis = self.x == this.x // 使用self和this是等价的
}
val a = new A
a.selfEqThis // 返回true,说明self和this等价
2. self的作用
在scala路径依赖的前提下,动态指定外部类
class Outer{
outer =>
val v1 = "here"
class Inner{
println(outer.v1) // 用outer表示外部类,相当于Outer.this
}
}
3. 使用this替换self的情形:类型约束
3.1 this不能直接替换self
class C{this => } //报错:error: not a legal formal parameter
3.2 声明类型
一个特例:唯一可以直接new的情形
class C{this: C => } // 不会报错:this一定是C类型
3.3 类定义中的声明类型
作为类型约束,检查this是否混入了指定的类型,此时的实例化必需使用with
trait X
class C{this: X => } // 类型约束声明可以发生在class的定义中
val c = new C // 报错:类型不匹配,error: class C cannot be instantiated because it does not conform to its self-type C with X
val c = new C with X // this:X约束类型场景1:实例化时必须混入X
class D extends C with X // this:X约束类型场景2:继承C时必须混入X
val d = new D
object A extends C with X // this:X约束类型场景3:对象继承C时必需混入X
3.4. 特质定义中的声明类型
作为类型约束,检查this是否混入了指定类型
trait T{this: X => } // 这种声明也可以发生在trait的定义中
trait T{this: X with Y with Z =>} // 类型约束可以是复合类型
trait X
trait Y
trait Z
val t = new T with X with Y with Z{} // 类型约束必需要求混入指定特质
val t = new T with X with Z with Y{} // 混入顺序可以任意排列
trait T{this: {def close():Unit} =>} // 类型约束可以是结构类型,类型结构是匿名类,此时的this是指左侧的类型必需具有方法close
val t = new T{def close() = println("close")} // 报错:此时的close为覆写,发生在this之后,应当想办法将结构类型的初始化前置
class A extends T{def close():Unit = println("close")} // 继承时混入:将结构类型的初始化提前到类型A中,此时在混入T之前,A中已经具有close方法
val a = new A
// 具有结构类型约束的特质无法通过实例化时混入来完成,因为结构类型无法继承和混入