Scala学习笔记(七)- Scala中的路径依赖类型(Path-dependent Type)和类型注入(Type Projection)

  |     |   本文总阅读量:

版权声明:本文原创,请勿转载,如有侵权请留言, 谢谢

引言

  以前从来没有听过什么叫类型注入,今天在读书时发现Scala有它独有的类型注入,原来在Scala里有两种机制来引用Scala里定义的类型:hash(#)和dot(.)操作符。

路径依赖类型(Path-dependent Type)

  对类型使用dot操作符可以想成与对象的成员用dot操作符有一样的效果。它指向某对象实例里找到的类型,称为路径依赖类型。如果一个方法是用特定类型的dot操作符定义的,该类型就绑定到特定的对象实例上,也就是说你不能在同个类的另外一个实例里使用同个类型来满足用dot操作符定义的类型约束,有点绕口,待会我们举个例子说明一下。

类型注入(Type Projection)

  hash操作符(#)要比dot操作符宽松,它被称作类型注入,类型注入是一种引用嵌套的类型而又不需要对象实例路径的方式,也就是说你可以引用嵌套的类型,如同未嵌套一样。有点抽象,我们来举个例子看看它月路径依赖类型的区别。

区别

  我们在REPL里定义一个Outer类,里面嵌套一个特质Inner:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
scala> class Outer {
| trait Inner
| def y = new Inner {}
| def foo(x: this.Inner) = "foo"
| def bar(x: Outer#Inner) = "bar"
| }
defined class Outer

scala> val x = new Outer
x: Outer = Outer@73ca34e7

scala> val y = new Outer
y: Outer = Outer@4f820f42

scala> x.y
res0: x.Inner = Outer$$anon$1@9df564f //类型显示为x.Inner,并不是Outer.Inner

scala> x.foo(x.y) //同实例类型检查通过
res1: String = foo

scala> x.foo(y.y) //不同实例类型检查失败
<console>:14: error: type mismatch;
found : y.Inner
required: x.Inner
x.foo(y.y)
^

scala> x.bar(y.y) //类型注入成功
res3: String = bar

  相信大家也看到了区别,首先我们在Outer的一个实例x里调用x.y,它的类型显示是x.Inner,而不是Outer.Inner,这就是我们前面所说的路径,所以我们将另外一个实例y的y.Inner传入x的foo方法是编译报错,因为foo方法用了dot操作符,是路径依赖类型。相反的是当我们传入x的bar方法时,可以正常编译,因为bar方法使用了hash操作符,是类型注入,不存在像foo一样的实例限制。
  这表明路径依赖类型需要同实例里的实例(foo.Bar),而类型注入能匹配任何实例里的实例(Foo#Bar),这便是路径依赖类型和类型注入的区别,路径依赖类型和类型注入这两个规则适用于全部的嵌套类型,包括用type关键字创建的类型

本质

  路径依赖类型实际上也是类型注入。路径依赖类型foo.Bar被编译器改写为foo.type#Bar。表达式foo.type指向Foo的单例类型,这个单例只能被名字foo所指向的实体所匹配。路径依赖类型要求foo.Bar要求Bar实例是在同个foo实例里创建的,而类型注入Foo#Bar会匹配任何Foo实例里的Bar实例。
  在Scala里,所有的类型引用都能被写成对命名实体的注入。类型scala.String是scala.type#String的快捷方式,名字scala指向scala包,类型String由scala包里的String类定义。
  使用伴生对象的路径依赖类时会有些麻烦,比如说bar.Foo有个伴生对象bar.Foo,那么类型bar.Foo(bar.type#Foo)指向特质的类型,而类型bar.Foo.type指向伴生对象的类型。

相关内容


坚持原创技术分享,您的支持将鼓励我继续创作,π(3.14)元就够啦!



文章目录
  1. 1. 引言
  2. 2. 路径依赖类型(Path-dependent Type)
  3. 3. 类型注入(Type Projection)
  4. 4. 区别
  5. 5. 本质
  6. 6. 相关内容
您是第 位小伙伴 | 本站总访问量 | 已经写了 659.9k 字啦

载入天数...载入时分秒...