Scala进阶之路-Scala中的高级类型

                            作者:尹正杰

版权声明:原创作品,谢绝转载!否则将追究法律责任。

一.类型(Type)与类(Class)的区别

  在Java里,一直到jdk1.5之前,我们说一个对象的类型(type),都与它的class是一一映射的,通过获取它们的class对象,比如 String.class, int.class, obj.getClass() 等,就可以判断它们的类型(type)是不是一致的。简单的说Type是用来描述类的,而Class是用来描述类的,因此Tpye范围要比Class描述的范围要更大一些!

  而到了jdk1.5之后,因为引入了泛型的概念,类型系统变得复杂了,并且因为jvm选择了在运行时采用类型擦拭的做法(兼容性考虑),类型已经不能单纯的用class来区分了,比如 List<String> 和 List<Integer> 的class 都是 Class<List>,然而两者类型(type)却是不同的。泛型类型的信息要通过反射的技巧来获取,同时java里增加了Type接口来表达更泛的类型,这样对于 List<String>这样由类型构造器和类型参数组成的类型,可以通过 Type 来描述;它和 List<Integer> 类型的对应的Type对象是完全不同的。

  在Scala里,类型系统又比java复杂很多,泛型从一开始就存在,还支持高阶的概念(后续会讲述)。所以它没有直接用Java里的Type接口,而是自己提供了一个scala.reflect.runtime.universe.Type(2.10后)。

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie import scala.reflect.runtime.universe._ class Teacher(name:String,age:Int){ } object AdvancedType {
def main(args: Array[String]): Unit = {
/**
* 注意,typeOf 和 classOf 方法接收的都是类型符号(symbol),并不是对象实例。
*/
val typeInfo = typeOf[Teacher] //在scala里获取类型信息是比较便捷的
println(typeInfo) val classInfo = classOf[Teacher] //同样scala里获取类(Class)信息也很便捷
println(classInfo)
}
} /*
以上代码执行结果如下:
cn.org.yinzhengjie.Teacher
class cn.org.yinzhengjie.Teacher
*/

二.classOf与getClass的区别

  获取Class时的两个方法:classOf 和 getClass。

  这种细微的差别,体现在类型赋值时,因为java里的 Class[Teacher]是不支持协变的,所以无法把一个Class[_ < : Teacher] 赋值给一个 Class[Teacher]。

三.结构类型

  结构类型是指一组关于抽象方法、字段和类型的规格说明,你可以对任何具备play方法的类的实例调用play方法,这种方式比定义特质更加灵活,是通过反射进行调用的。简单来说,就是只要是传入的类型,符合之前定义的结构的,都可以调用。

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie class Structure {
def play() = println("play方法调用了")
} object AdvancedType extends App {
/**
* type关键字是把 = 后面的内容命名为别名。
*/
type X = {
def play(): Unit
} /**
* 定义本地方法,将X类型传入
*/
def init(res: X) = {
res.play
} /**
* 调用init的方法,需要传入一个实现X对象的paly方法
*/
init(new {
def play() = println("Play再一次")
}) /**
* 结构类型,简单来说,就是只要是传入的类型,符合之前定义的结构的,都可以调用。
*/
object A {
def play() {
println("A object play")
}
} init(A) val structure = new Structure
init(structure)
} /*
以上代码执行结果如下:
Play再一次
A object play
play方法调用了
*/

四.中置类型

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie object AdvancedType extends App {
/**
* 中置类型是一个带有两个类型参数的类型,以中置语法表示,比如可以将Map[String, Int]表示为:
*/
val scores: String Map Int = Map("yinzhengjie" -> 100)
println(scores)
} /*
以上代码执行结果如下:
Map(yinzhengjie -> 100)
*/

五.自身类型

  对于this别名 yinzhengjie=>这种写法形式,是自身类型(yinzhengjie type)的一种特殊方式。yinzhengjie在不声明类型的情况下,只是this的别名,所以不允许用this做this的别名。案例如下:

 /*
@author :yinzhengjie
Blog:http://www.cnblogs.com/yinzhengjie/tag/Scala%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
EMAIL:y1053419035@qq.com
*/
package cn.org.yinzhengjie class A {
/**
* yinzhengjie => 这句相当于给this起了一个别名叫yinzhengjie,
* 注意 : yinzhengjie并不是关键字,可以用除了this外的任何名字命名(除关键字)。
*/
yinzhengjie =>
val x = 100
def foo = yinzhengjie.x + this.x
} /**
* 注意,这里的yinzhengjie是给外部的Outer起了一个别名叫做yinzhengjie
*/
class Outer { yinzhengjie =>
val v1 = "here"
//定义一个Scala内部类
class Inner {
val v1 = "there"
println(yinzhengjie.v1) // 用yinzhengjie表示外部类(起了个别名),相当于Outer.this.v1
}
new Inner
println(this.v1)
println(Outer.this.v1)
} object AdvancedType extends App {
new Outer val res = new A
println(res.foo)
} /*
以上代码执行结果如下:
here
here
here
200
*/

六.运行时反射

  关于Scala高级类型还有很多,我这里就不一一列举啦,比如:复合类型,类型别名,类型投影,单例类型等等。对了,关于反射的笔记请参考:https://www.cnblogs.com/yinzhengjie/p/9385123.html

Scala进阶之路-Scala中的高级类型的更多相关文章

  1. Scala进阶之路-Scala高级语法之隐式(implicit)详解

    Scala进阶之路-Scala高级语法之隐式(implicit)详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 我们调用别人的框架,发现少了一些方法,需要添加,但是让别人为你一 ...

  2. Scala进阶之路-Scala中的枚举用法案例展示

    Scala进阶之路-Scala中的枚举用法案例展示 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. Scala中的枚举值和Java中的枚举值有点差别,不过使用起来也都差大同小异,我这 ...

  3. Scala进阶之路-Scala中的Ordered--Ordering

    Scala进阶之路-Scala中的Ordered--Ordering 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任.   说道对象的比较,在Java中大家最熟悉不过的就是实现类本身实 ...

  4. Scala进阶之路-Scala中的泛型介绍

    Scala进阶之路-Scala中的泛型介绍 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 通俗的讲,比如需要定义一个函数,函数的参数可以接受任意类型.我们不可能一一列举所有的参数类 ...

  5. Scala进阶之路-Scala函数篇详解

    Scala进阶之路-Scala函数篇详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.传值调用和传名调用 /* @author :yinzhengjie Blog:http: ...

  6. Scala进阶之路-Scala的基本语法

    Scala进阶之路-Scala的基本语法 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.函数式编程初体验Spark-Shell之WordCount var arr=Array( ...

  7. Scala进阶之路-Scala特征类与unapply反向抽取

    Scala进阶之路-Scala特征类与unapply反向抽取 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Scala特征类分析 1>.Unit 答:用于定义返回值类型, ...

  8. Scala进阶之路-高级数据类型之集合的使用

    Scala进阶之路-高级数据类型之集合的使用 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. Scala 的集合有三大类:序列 Seq.集 Set.映射 Map,所有的集合都扩展自 ...

  9. Scala进阶之路-高级数据类型之数组的使用

    Scala进阶之路-高级数据类型之数组的使用 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.数组的初始化方式 1>.长度不可变数组Array 注意:顾名思义,长度不可变数 ...

随机推荐

  1. 搭建ssm的步骤

    搭建SSM的步骤 ----------------------------- 1.创建web工程 2.把SSM做需要的所有jar导入工程中 3.web.xml 1.Springmvc的前端控制器,如果 ...

  2. ajax 异步请求 代码

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding= ...

  3. HDU 2087 剪花布条 (字符串哈希)

    http://acm.hdu.edu.cn/showproblem.php?pid=2087 Problem Description 一块花布条,里面有些图案,另有一块直接可用的小饰条,里面也有一些图 ...

  4. [转帖]什么是Asp.net Core?和 .net core有什么区别?

    什么是Asp.net Core?和 .net core有什么区别? https://www.cnblogs.com/itzhangxp/p/8322364.html 知道微软开始用 kestrel了 ...

  5. C++的内存分区

    C++的内存划分为栈区.堆区.全局区/静态区.字符串常量和代码区. 栈区 由系统进行内存的管理. 主要存放函数的参数以及局部变量.在函数完成执行,系统自行释放栈区内存,不需要用户管理.整个程序的栈区的 ...

  6. mysql理论结合实际篇(一)

    最近两天做需求,是要将退款和退货报表里使用的临时表改用固定表, 自己建表时,如(只是举例): CREATE TABLE tasks ( task_id INT UNSIGNED NOT NULL AU ...

  7. python2 高级编程

    第一 正则表达式 1. 正则表达式意义 正则表达式是高级文本匹配模式,为搜索,匹配,替换提供了基础 2. 搜索与匹配的区别 搜索指在字符串任何部分查找 匹配指在字符串起始处查找 3. 编写正则表达式 ...

  8. Luogu4512 【模板】多项式除法(多项式求逆+NTT)

    http://blog.miskcoo.com/2015/05/polynomial-division 好神啊! 通过翻转多项式消除余数的影响,主要原理是商只与次数不小于m的项有关. #include ...

  9. TP5报错总结

    LNMP一键安装包上部署TP5项目500错误或者空白解决 [问题原因] TP5的入口文件在public下,当他调用类文件时,跨目录所以造成500错误,或者一片空白的问题 [解决方法] 1.public ...

  10. 微信access_token请求之简单缓存方法封装

    还有东西要搞,就直接上代码 function.php <?php // 一个好玩的 curl 类 // https://github.com/metowolf/Meting/blob/maste ...