Scala 自身类型(self-type) 解析
Scala 有一个自身类型(self-type) 的东西,由来已久,居然今天才发现。如果一个类或 trait 指明了 self-type 类型(包括类和特质),它的子类型或是对象也必须是相应的类型。它产生的效果与继承(或 mixin) 颇有几分相似。self-type 的语法是
上面
注(2018-02-14): 这个语法只是用作 this 别名的话,后面可以不用接类型,例如
如果在声明

如果
由于前面
还有一种结构类型的
定义中声明了
要求在 Tweeter 中必须实现该方法,如
最后,注意一下
以上代码编译没有问题,但创建的
链接:
永久链接 https://yanbin.blog/scala-self-type-understanding/, 来自 隔叶黄莺 Yanbin's Blog
[版权声明]
本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。
this 的别名: 某一类型(class 或 trait), 直接看一个例子: 1class User(val name: String)
2
3trait Tweeter {
4 this: User => //这个表示 Tweeter 本身也必须是一个 User,它的子类型必须想办法符合这一要求
5 def tweet(tweetText: String) = {
6 println(s"$name: $tweetText")
7 }
8}
9
10class VerifiedTweeter(val username: String)
11 extends User(username) with Tweeter { //Tweeter 要求这个类必须是一个 User, 所以需要继承自 User 类
12}
13
14val v = new VerifiedTweeter("Yanbin")
15v.tweet("Hello")上面
this: User => 中的 this 只是一个别名,可以是 self 或任何有效标识(如 abc: User),这里使用 this 等于未指定别名,与原本的 this 重叠了。如果声明为非 this 的话则可以这么用1trait Tweeter {
2 abc: User =>
3 def tweet(tweetText: String) = {
4 println(s"${this.name}-${abc.name}: $tweetText")
5 }
6}this 永远都在,同时 abc 与 this 是完全一样的效果。注(2018-02-14): 这个语法只是用作 this 别名的话,后面可以不用接类型,例如
1trait Tweeter {
2 abc =>
3 .... //代码中 abc 就是 this 的别名,它们是等效的
4}如果在声明
VerifiedTweeter 类只是混入 Tweeter 特质会怎么样呢?以下两种声明都将产生同样的编译错误
如果
User 也是一个 trait,那么声明 VerifiedTweeter1 时可以同时混入 User, 即1trait VerifiedTweeter1 extends Tweeter with User由于前面
User 也是一个类,所以需要让 mixin Tweeter 的类继承自 User , 就是1class VerifiedTweeter(val username: String)
2 extends User(username) with Tweeter {
3}self-type 可以指定多重类型,那么声明子类型或创建实例时也要符合多种类型 1trait User
2trait Animal
3
4trait Tweeter {
5 this: User with Animal =>
6}
7
8class VerifiedTweeter extends Tweeter with User with Animal
9
10//直接创建实例
11new Tweeter with User with Animal还有一种结构类型的
self-type, 更像是匿名类型的 self-type, 不是指定类型名而是类型必须实现的方法,例如
定义中声明了this: {def say: Unit} =>
要求在 Tweeter 中必须实现该方法,如
1class Tweeter extends User {
2 def say: Unit = {
3 println("say something")
4 }
5}
6
7//或者创建匿名的 User 类及实例
8val user = new User {
9 def say: Unit = {
10 println("say something")
11 }
12}最后,注意一下
this: User => 这个语法后不能用大括号括起后续的代码1trait Tweeter {
2 this: User => {
3 def tweet(tweetText: String) = {
4 println(s"$name: $tweetText")
5 }
6 }
7}以上代码编译没有问题,但创建的
Tweeter 实例是看不到 tweet(...) 方法的。链接:
永久链接 https://yanbin.blog/scala-self-type-understanding/, 来自 隔叶黄莺 Yanbin's Blog
[版权声明]
本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。