您的位置:首页 > 其它

scala类型系统:9) this别名&自身类型

2016-11-09 09:51 120 查看


scala类型系统:9) this别名&自身类型

看scala的源码的话很发现很多源码开头都有一句:
self =>
 这句相当于给
this
起了一个别名为
self

class A {
self =>  //this别名
val x=2
def foo = self.x + this.x
}


self
不是关键字,可以用除了
this
外的任何名字命名(除关键字)。就上面的代码,在A内部,可以用
this
指代当前对象,也可以用
self
指代,两者是等价的。

它的一个场景是用在有内部类的情况下:
class Outer { outer =>
val v1 = "here"
class Inner {
println(outer.v1) // 用outer表示外部类,相当于Outer.this
}
}


对于this别名 
self =>
这种写法形式,是自身类型(self
type)的一种特殊方式。

self
在不声明类型的情况下,只是this的别名,所以不允许用this做this的别名
scala> class C { this => } //error 不能用this做别名


但当声明了类型的时候,就不是别名的用途了,这个时候表示
自身类型
,比如:
scala> class C { this:X => }


this:X =>
 要求C在实例化时或定义C的子类时,必须混入指定的
X
类型,这个
X
类型也可以指定为当前类型
scala> class C { this:C => } // 不会报错


自身类型的存在相当于让当前类变得“抽象”了,它假设当前对象(this)也符合指定的类型,因为自身类型 
this:X =>
的存在,当前类构造实例时需要同时满足
X
类型
scala> new C // 不满足
<console>:10: error: class C cannot be instantiated because it does not conform to its self-type C with X

// ok, 相当于构造一个复合类型(C with X)的实例
scala> val c = new C with X


在定义C的子类时,因为自身类型的约束,也必须满足
X
类型,即子类必须也混入
X

scala> class D extends C with X


注意上面两种情况下
X
都为特质(trait)。

如果自身类型是定义在特质中(大多情况下):
scala> trait T { this:X => }


那么当某个class或object 要继承或混入 T 时,必须也要满足 X 类型,如果该类/单例不是X的子类的话就要同时混入X才可以
scala> object A extends T with X


最后,自身类型也可以声明为复合类型
this: X with Y with Z =>


或声明为结构类型
this: { def close:Unit} =>


另外,自身类型中,可以用
this
也可以用其他名字,如
self


转载自:http://hongjiang.info/scala/   推荐大家阅读下这位大哥出版的书《Scala函数式编程》
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: