Scala入门到精通——第二十四节 高级类型 (三)

  • 时间:
  • 浏览:0
  • 来源:uu快3下载网址_uu快3IOS下载_电脑版

不可能 类型擦除的影响,编译期居于的类型信息在编译后不居于了,在应用应用程序时那么获取该信息,但或者 场景下不可能 都要得到编译期的类型信息,scala才能做到或者 点,它通过Manifest和TypeTag来保存类型信息并在运行时使用该信息。那Manifest与TypeTag有那此区别呢?Manifest在scala.reflect包中,它在scala.reflect包中,而TypeTag 在scala.reflect.runtime.universe包中定义;TypeTag能那么用来替代Manifest,功能更强大或者 ,Manifest那么识别路径依赖类型,类似对于class Outter{ class Inner},假设分别创建了有两个 不同的外部类,outter.Inner, outter2.Inner, Manifest就会识别为同一类型,而TypeTag不想,另外TypeTag能那么使用typeOf[T] 来检查类型参数。

能那么看到,Function1类也进行了类型专门化。

作者:摆摆少年梦

视频地址:http://blog.csdn.net/wsscy60 4/article/details/38440247

上述代码编译也有生成下列字代码文件,如下图

经过类型擦除后的类称为原始类型,从这点来看,java中的泛型人太好是有两个 伪泛型,它只在编译层次进行实现,在生成字码码这偏离 泛型信息被擦除。下面的例子证明也证明了或者 点:

下面的代码给出了Manifest的用法:

从里边的代码能那么看到,typeTag返回的是具体的类型,而也有类型擦除如果 的类型any,即TypeTag保存所有具体的类型。在运行时能那么通过模式匹配来精确地对类型进行判断:

自动装箱与拆箱都要损耗一定的性能,当性能要求较高时都要应用程序员手动云进行转换。Scala中的Type Specialization避免了那此问提。它的语法很简单,通过注解进行类型专门化声明,如:

隐式参数m由编译器根据上下文自动传入,类似print1(List(“one”, “two”)) ,编译器会根据”one”,”two” 实际类型推断出 T 的类型是 String,再隐式地传入了Manifest[String]类型的对象参数,使得运行时能那么根据或者 参数做更多的事情。

下面的代码演示了拆箱(unboxing)

里边的typeOf[A]在传入参数为List(“String”)时,得到结果是java.lang.String。typeOf[A]接受有两个 类型为TypeTag[a]的隐式参数,编译器生成的TypeTag隐式参数会被传给typeOf[A] 。 有4种TypeTag:

@specialized 还能那么更细致,限定某个或有几个基本类型,类似:

2 自动装箱与拆箱

到此,Scala的类型系统基本介绍完毕,下表给出了Scala中常见的类型

在scala中,类(class)与类型(type)是有两个 不一样的概念。大伙知道类是对同一类型数据的抽象,而类型则更具体。比如定义class List[T] {}, 能那么有List[Int] 和 List[String]等具体类型,称List为类,而List[Int]、List[String]则为类型。从这方面看:类型一致的对象它们的类也是一致的;而类一致的,其类型不一定一致。类似:

java中的类型擦除会引起或者 问提,具体能那么参考http://blog.csdn.net/lonelyroamer/article/details/7868820

经过类型擦除后,最终变为:

在前面给的示例代码中,大伙直接使用

Person<Integer> p2=new Person<Integer>(1, 23);

都要注意的是这里使用的是java的基本类型进行对象的创建,而给定的具体类型是Integer,此时Java会你要们自动进行转换,或者 转换操作被称为自动装箱(autoboxing),里边的代码大约:Person<Integer> p2=new Person<Integer>(Integer.valueOf(1), Integer.valueOf(23));

1 类型擦除

假设大伙利用Java泛型定义了下面的Person类:

Type Specialization,一般被翻译成类型专门化,它主而是 用来避免泛型的类型擦除和自动装箱拆箱的问提。在JAVA语言当中,泛型生成字节码文件也有进行泛型类型擦除,类型擦除后利用上界类型(一般是Object)来替代,但那么 做句子有问提,这是不可能 在Java语言中基本类型与对象类型是那么相互引用的,java中的基本类型那么使用泛型。避免方案是利用对应的对象类型来进行替代,类似int对应Integer类型,但或者 土法律法律依据并非能避免根本问提。为方便里边Type Specialization的理解,大伙先从java的类型擦除、自装箱与拆箱讲起。

本节内容大多来源于自官方文档http://docs.scala-lang.org/overviews/reflection/typetags-manifests.html,大伙在学习的如果 ,可看打开API文档,对本节内容进行理解。

下面的代码演示了如保使用TypeTag

1 scala.reflect.api.TypeTags#TypeTag. A full type descriptor of a Scala type. For example, a TypeTag[List[String]] contains all type information, in this case, of typescala.List[String].

2 scala.reflect.ClassTag. A partial type descriptor of a Scala type. For example, a ClassTag[List[String]] contains only the erased class type information, in this case, of type

3 scala.collection.immutable.List.ClassTags provide access only to the runtime class of a type. Analogous to scala.reflect.ClassManifest.

4 scala.reflect.api.TypeTags#WeakTypeTag. A type descriptor for abstract types (see corresponding subsection below).

这给出最常用的ClassTag的用法:ClassTag[T]保存了被泛型擦除后的原始类型T,提供给运行时应用程序使用。

从图中能那么看到,共生成了九个版本的List,其中这九个文件分别对应scala中的九种基本类型即Unit, Boolean, Byte, Short, Char, Int, Long, Float, Double。感兴趣的能那么利用javap命令进行查看,这里给出其Byte类型的实现:

在上一讲中大伙看到了Function1及Function2的类定义中也使用@specialize进行注解,如:

去掉 公众微信号,能那么了解更多最新Spark、Scala相关技术资讯