【Scala类型系统】自身类型(self type)引用
定义
特质能够要求混入它的类扩展自还有一个类型,可是当使用自身类型(self type)的声明来定义特质时(this: ClassName =>)。这种特质仅仅能被混入给定类型的子类其中。
如果尝试将该特质混入不符合自身类型所要求的类时,就会报错。
从技术角度上看。自身类型是在类中提到this时,对于this的如果性类型。从有用角度上看,自身类型指定了对于特质能够混入的详细类的需求。如果你的特质仅用于混入还有一个或几个特质。那么能够指定那些如果性的特质。
自身类型在依赖注入的应用
在通过组件构建大型系统,而每一个组件都有不同的实现的时候。我们须要将组件的不同选择组装起来。
通常组件之间存在某种依赖关系,比方,数据訪问组件可能会依赖日志功能。
每一个组件都描写叙述了它所依赖的其它组件的接口,而对实际组件实现的引用是在应用程序被组件起来的时候“注入”的。
对于Scala来说,能够通过特质和自身类型达到简单的依赖注入的效果。
自身类型实现依赖注入
对于日志功能trait Logger {def log(msg: String)},它有两个实现:ConsoleLogger和FileLogger。
用户认证特质有对日志功能的依赖,用于记录认证失败:
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)引用的更多相关文章
- scala类型系统 type关键字
和c里的type有点像. scala里的类型,除了在定义class,trait,object时会产生类型,还可以通过type关键字来声明类型. type相当于声明一个类型别名: scala> t ...
- Scala类型系统——高级类类型(higher-kinded types)
高级类类型就是使用其他类型构造成为一个新的类型,因此也称为 类型构造器(type constructors).它的语法和高阶函数(higher-order functions)相似,高阶函数就是将其它 ...
- scala类型系统:24) 理解 higher-kinded-type
首先我们从最基本的泛型来看: 现在我们对上面泛型中的类型参数再进一步,也是个泛型会如何呢? 可以看到,java中不支持类型参数也是泛型类型的情况,而scala支持.这是一个很重要的区别,scala在类 ...
- 第54讲:Scala中复合类型实战详解
今天学习了scala的复合类型的内容,让我们通过实战来看看代码: trait Compound_Type1trait Compound_Type2class Compound_Type extends ...
- 第53讲:Scala中结构类型实战详解
今天学习了scala的结构类型,让我们看看代码 class Structural {def open() = print("A class interface opened") } ...
- Scala 深入浅出实战经典 第54讲:Scala中复合类型实战详解
王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-64讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...
- Scala 深入浅出实战经典 第53讲:Scala中结构类型实战详解
王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-64讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...
- Scala的Option类型
Scala的Option类型 为了让所有东西都是对象的目标更加一致,也为了遵循函数式编程的习惯,Scala鼓励你在变量和函数返回值可能不会引用任何值的时候使用Option类型.在没有值的时候,使用No ...
- 反射,得到Type引用的三种方式
1.使用System.Object.GetType()得到Type引用 使用一个SportsCar实例得到类型信息 SportsCar sc=new SportsCar(); Type t=sc.G ...
随机推荐
- linux随笔4
vim编辑器: 启动vim编辑器,只需键入vim 和希望编辑的文件:vim mongo.sh 如果文件存在,将显示整个内容显示到进行编辑的缓冲区,如果文件不存在,打开一个新的缓冲区进行编辑. 内容未占 ...
- python常用方法总结
1.os模块的路径拼接: import os now_path=os.path.abspath(__file__)#当前运行文件的路径 print(now_path) uppeer_path=os.p ...
- tensorflow——MNIST机器学习入门
将这里的代码在项目中执行下载并安装数据集. 执行下面代码,训练.并评估模型: # _*_coding:utf-8_*_ import inputdata mnist = inputdata.read_ ...
- [错误解决]刚拿到的服务器vim退格键(backspace)失灵
刚拿到的服务器vim退格键(backspace)失灵: 解决方案: 在主目录下建立.vimrc 覆盖/etc/vimrc的配置 .vimrc 与 /etc/vimrc的区别: 在启动的时候vim会读取 ...
- 解决Failed with error: unable to access 'https://git.coding.net/chenmi1234/lianpos.git/': Couldn't resolve host 'git.coding.net'
代码改变世界 github push 出现问题 Failed with error: unable to access 'https://git.coding.net/chenmi1234/lianp ...
- LibreOJ2085 - 「NOI2016」循环之美
Portal Description 给出\(n,m(n,m\leq10^9)\)和\(k(k\leq2000)\),求在\(k\)进制下,有多少个数值不同的纯循环小数可以表示成\(\dfrac{x} ...
- linux--bash: redis-server: 未找到命令
linux 安装redis过程中出现了异常,make不通过,异常如下: [root@localhost redis-2.8.3]# make cd src && make all ma ...
- poj 3109
...
- Windows server 2008 R2 + IIS7.5,ASP网站设置
Windows server 2008 R2 + IIS7.5,ASP网站设置 1. 让IIS7支持ASP Win2008 IIS7 默认不安装ASP,如果需要ASP 的支持,需要将这个角色服务选上. ...
- Oracle学习记录1
1.current_date与sysdate区别 在oracle中current_date与sysdate都是显示当前系统时间, 其结果基本相同,但是有三点区别:a. current_date返回的是 ...