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

  • 时间:
  • 浏览:1

在上一讲中亲戚亲戚朋友看得人了Function1及Function2的类定义中也使用@specialize进行注解,如:

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).

回会 看得人,Function1类也进行了类型专门化。

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

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

@specialized 还回会 更细致,限定某个或十哪几个 基本类型,例如:

从上边的代码回会 看得人,typeTag返回的是具体的类型,而有的是类型擦除以前 的类型any,即TypeTag保存所有具体的类型。在运行时回会 通过模式匹配来精确地对类型进行判断:

在scala中,类(class)与类型(type)是三个白 多多 多不一样的概念。亲戚亲戚朋友知道类是对同一类型数据的抽象,而类型则更具体。比如定义class List[T] {}, 回会 有List[Int] 和 List[String]等具体类型,称List为类,而List[Int]、List[String]则为类型。从这方面看:类型一致的对象它们的类也是一致的;而类一致的,其类型不一定一致。例如:

2 自动装箱与拆箱

java中的类型擦除会引起什儿 现象,具体回会 参考http://blog.csdn.net/lonelyroamer/article/details/7868820

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

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

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

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

1 类型擦除

假设亲戚亲戚朋友利用Java泛型定义了下面的Person类:

作者:摆摆少年梦

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

以前 类型擦除的影响,编译期处于的类型信息在编译后不处于了,在应用应用线程时也能获取该信息,但什儿 场景下以前 须要得到编译期的类型信息,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] 来检查类型参数。

加在公众微信号,回会 了解更多最新Spark、Scala相关技术资讯

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

自动装箱与拆箱须要损耗一定的性能,当性能要求较高时须要应用线程员手动云进行转换。Scala中的Type Specialization补救了哪几种现象。它的语法很简单,通过注解进行类型专门化声明,如:

上述代码编译一定会生成下列字代码文件,如下图

在前面给的示例代码中,亲戚亲戚朋友直接使用

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

须要注意的是这里使用的是java的基本类型进行对象的创建,而给定的具体类型是Integer,此时Java会帮亲戚亲戚朋友自动进行转换,什儿 转换操作被称为自动装箱(autoboxing),上边的代码最少:Person<Integer> p2=new Person<Integer>(Integer.valueOf(1), Integer.valueOf(23));

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

下面的代码演示了咋样使用TypeTag

经过类型擦除后的类称为原始类型,从这点来看,java中的泛型实在是三个白 多多 多伪泛型,它只在编译层次进行实现,在生成字码码这次责泛型信息被擦除。下面的例子证明也证明了什儿 点:

Type Specialization,一般被翻译成类型专门化,它主并且我用来补救泛型的类型擦除和自动装箱拆箱的现象。在JAVA语言当中,泛型生成字节码文件一定会进行泛型类型擦除,类型擦除后利用上界类型(一般是Object)来替代,但也能 做一段话有现象,这是以前 在Java语言中基本类型与对象类型是也能相互引用的,java中的基本类型也能使用泛型。补救方案是利用对应的对象类型来进行替代,例如int对应Integer类型,但什儿 措施不要能补救根本现象。为方便上边Type Specialization的理解,亲戚亲戚朋友先从java的类型擦除、自装箱与拆箱讲起。

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