您的位置:首页 > 其它

scala类型系统:17) 结构类型的细节问题

2016-11-15 23:16 337 查看


scala类型系统:17) 结构类型的细节问题

这次聚会中分享的《scala类型系统》中,对于结构类型,有一页中有错误,纠正一下。



这页ppt中,上面一行代码中的 
{val name:String}
 是结构类型,但下面一行中
{val
name="wang"}
在这种情况下并不是结构类型,而是Early definition

我们看一下scala规范里对Early definition的定义:
{   val p1:T1 =e1
...
val pn: Tn = en
} with sc with mt1 with mtn {stats}


在这种情况下,大括号这部分并不是结构类型,只是相当于把部分成员在父类初始化之前提前初始化而已。大括号后边的
sc
 是指父类构造器。

然后再说说对结构类型的理解,还是那页ppt里的例子:
trait T extends { val name:String }


等价于
trait T extends AnyRef { val name:String }


在scala语言规范描述复合类型(compound type)时,也说到:

A compound type may also consist of just a refinement {R } with no preceding component types. Such a type is equivalent to AnyRef{R }.

复合类型可以只是 
{refinement}
 部分,前边可以不要其他 component type,它等价于
AnyRef{refinement}
 ,这么看结构类型算是复合类型的一个特例。

在scala语言规范里,也没有专门定义“结构类型”的章节,只是在2.6版本修订时,提到可以声明结构类型:

Changes in Version 2.6 (27-July-2007) It is now possible to declare structural types using type refinements (§3.2.7).

结构类型中的”structural“这个词也是来自规范对compound type描述时:
{refinement}
 部分如果包含声明或类型定义(没有覆盖其他component
type),则说这部分的声明或定义是“结构化的”。

A compound type 
T1 with . . . with Tn {R }
 represents objects with members as given in the component
types 
T1, ..., Tn
 and the refinement 
{R
}
. A refinement 
{R }
 contains declarations and type definitions. If a declaration or definition overrides a declaration or definition
in one of the component types T1, …, Tn, the usual rules for overriding apply; otherwise the declaration or definition is said to be “structural”.

另外对于结构类型中的类型参数,还有一个约束,看下面的例子:
scala> def f( p: {def id[T](i:T) } ) {
//donothing
}
f: (p: AnyRef{def id[T](i: T): Unit})Unit


上面f函数的参数p 是一个结构类型,它内部声明了一个方法
id
,该方法带有类型参数。如果类型参数是在结构类型自己的上下文定义的(上面的情况),编译和运行都没有问题:
scala> f( new { def id[String](i:String)=print(i) })
//运行ok


但如果结构类型中声明的方法需要外部的类型参数,比如:
scala> def f[T]( p: {def id(i:T) } ) {
//donothing
}
<console>:7: error: Parameter type in structural refinement may not refer to an abstract type defined outside that refinement


编译时会有错误,提示不能使用定义在外部的抽象类型。但是对于返回值使用外部的类型参数却没有问题:
scala> def f[T]( p: {def id():T } ) {
//donothing
}
//编译ok f: [T](p: AnyRef{def id(): T})Unit


这个原因是scala在jvm上实现,受限于jvm运行时采取的类型擦拭,结构类型背后通过反射来执行的,丢失了类型信息所致。细节解释可以参考:这里

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