定义

特质能够要求混入它的类扩展自还有一个类型,可是当使用自身类型(self type)的声明来定义特质时(this: ClassName =>)。这种特质仅仅能被混入给定类型的子类其中。

如果尝试将该特质混入不符合自身类型所要求的类时,就会报错。

从技术角度上看。自身类型是在类中提到this时,对于this的如果性类型。从有用角度上看,自身类型指定了对于特质能够混入的详细类的需求。如果你的特质仅用于混入还有一个或几个特质。那么能够指定那些如果性的特质。

自身类型在依赖注入的应用

在通过组件构建大型系统,而每一个组件都有不同的实现的时候。我们须要将组件的不同选择组装起来。

通常组件之间存在某种依赖关系,比方,数据訪问组件可能会依赖日志功能。

每一个组件都描写叙述了它所依赖的其它组件的接口,而对实际组件实现的引用是在应用程序被组件起来的时候“注入”的。

对于Scala来说,能够通过特质和自身类型达到简单的依赖注入的效果。

自身类型实现依赖注入

对于日志功能trait Logger {def log(msg: String)},它有两个实现:ConsoleLoggerFileLogger

用户认证特质有对日志功能的依赖,用于记录认证失败:

trait Auth {
this: Logger =>
def login(id: String, password: String): Boolean
}

应用逻辑依赖于上述两个特质,如此定义:

trait App {
this: Logger with Auth =>
...
}

然后我们能够组装应用。object MyApp extends App with FileLogger("test.log") with MockAuth("users.txt")。这里将组件黏合成了一个大类型。

蛋糕模式实现组件配置设计

蛋糕模式能够给出更好的设计。对每一个服务都提供一个组件特质。

组件特质包括:

  • 不论什么所依赖的组件,以自身类型表述
  • 描写叙述服务接口的特质
  • 抽象的val。该val将被初始化成服务的一个实例
  • 能够有选择地包括服务接口的实现
trait LoggerComponent {
trait Logger {...}
val logger: Logger
class FileLogger(file: String) extends Logger {...}
...
} trait AuthComponent {
this: LoggerComponent => //自身类型使得能够訪问日志器 trait Auth {...}
val auth: Auth
class MockAuth(file: String) extends Auth {...}
...
}

这段代码中,我们使用自身类型表示认证组件对日志器组件的依赖。

通过在程序中进行组件配置能够让编译器帮助我们校验模块间的依赖关系:

object AppComponents extends LoggerComponent with AuthComponent {
val logger = new FileLogger("test.log")
val auth = new MockAuth("user.txt")
}

转载请注明作者Jason Ding及其出处

jasonding.top

Github博客主页(http://blog.jasonding.top/)

CSDN博客(http://blog.csdn.net/jasonding1354)

简书主页(http://www.jianshu.com/users/2bd9b48f6ea8/latest_articles)

Google搜索jasonding1354进入我的博客主页

【Scala类型系统】自身类型(self type)引用的更多相关文章

  1. scala类型系统 type关键字

    和c里的type有点像. scala里的类型,除了在定义class,trait,object时会产生类型,还可以通过type关键字来声明类型. type相当于声明一个类型别名: scala> t ...

  2. Scala类型系统——高级类类型(higher-kinded types)

    高级类类型就是使用其他类型构造成为一个新的类型,因此也称为 类型构造器(type constructors).它的语法和高阶函数(higher-order functions)相似,高阶函数就是将其它 ...

  3. scala类型系统:24) 理解 higher-kinded-type

    首先我们从最基本的泛型来看: 现在我们对上面泛型中的类型参数再进一步,也是个泛型会如何呢? 可以看到,java中不支持类型参数也是泛型类型的情况,而scala支持.这是一个很重要的区别,scala在类 ...

  4. 第54讲:Scala中复合类型实战详解

    今天学习了scala的复合类型的内容,让我们通过实战来看看代码: trait Compound_Type1trait Compound_Type2class Compound_Type extends ...

  5. 第53讲:Scala中结构类型实战详解

    今天学习了scala的结构类型,让我们看看代码 class Structural {def open() = print("A class interface opened") } ...

  6. Scala 深入浅出实战经典 第54讲:Scala中复合类型实战详解

    王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-64讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...

  7. Scala 深入浅出实战经典 第53讲:Scala中结构类型实战详解

    王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-64讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...

  8. Scala的Option类型

    Scala的Option类型 为了让所有东西都是对象的目标更加一致,也为了遵循函数式编程的习惯,Scala鼓励你在变量和函数返回值可能不会引用任何值的时候使用Option类型.在没有值的时候,使用No ...

  9. 反射,得到Type引用的三种方式

    1.使用System.Object.GetType()得到Type引用 使用一个SportsCar实例得到类型信息 SportsCar sc=new  SportsCar(); Type t=sc.G ...

随机推荐

  1. Jmeter Cluster

    Jmeter 是开源软件,100%纯java应用程序,专门为负载测试和性能测试. Jmeter的特性包括: 1.负载测试和性能测试许多不同的服务器/协议类型: Web - HTTP, HTTPS SO ...

  2. python列出指定目录下的所有目录和文件

    import os import docx def scanfile(rootdir): result = [] for f in os.walk(rootdir): for files in f[2 ...

  3. js中的原型哲学思想

    https://segmentfault.com/a/1190000005824449 记得当年初试前端的时候,学习JavaScript过程中,原型问题一直让我疑惑许久,那时候捧着那本著名的红皮书,看 ...

  4. poj3255 Roadblocks 次短路

    Roadblocks Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 10098   Accepted: 3620 Descr ...

  5. Docker网络基础:快速指南

    Docker网络基础:快速指南 原文连接:http://blogxinxiucan.sh1.newtouch.com/2017/07/30/Docker网络基础:快速指南/ 了解有关扩展网络功能的默认 ...

  6. 【bzoj4785】[Zjoi2017]树状数组 线段树套线段树

    题目描述 漆黑的晚上,九条可怜躺在床上辗转反侧.难以入眠的她想起了若干年前她的一次悲惨的OI 比赛经历.那是一道基础的树状数组题.给出一个长度为 n 的数组 A,初始值都为 0,接下来进行 m 次操作 ...

  7. hihoCoder #1157 建造金字塔

    这道题我想了一天才想清楚做法.AC 了之后去看别人写的题解,都是三言两语意识流式描述,我并不能读懂.我觉得很自卑,为何人家解这道题如此轻松.不过,我还是决定把我的解法写下来,并且一定要写清楚. 思路 ...

  8. 使用Matlab实现对图片的缩放

    在做图像处理的时候,有时需要对图片的像素进行放大或则缩小. 使用Matlab很容易实现对图像的放大和缩小.这里只讲缩放到固定像素的方法. clear; clc; %清除以前的数据 folderName ...

  9. bzoj 1185 [HNOI2007]最小矩形覆盖 凸包+旋转卡壳

    题目大意 用最小矩形覆盖平面上所有的点 分析 有一结论:最小矩形中有一条边在凸包的边上,不然可以旋转一个角度让面积变小 简略证明 我们逆时针枚举一条边 用旋转卡壳维护此时最左,最右,最上的点 注意 注 ...

  10. Codeforces878E. Numbers on the blackboard

    $n \leq 100000$的数列,数字范围$-1e9,1e9$,现$q \leq 1e5$个每次问在一个区间玩游戏,能得到的最大的数.“游戏”:选相邻两个数$a_x,a_y$,然后把他们删掉,变成 ...