本文链接:Scala学习(四)——类型
简介
作为一个强类型语言,类型是语言中很重要的一部分。和Java相比,Scala的类型更加丰富。
基本类型
Scala没有基本类型,所有对应Java中的基本类型都是类:
| Java基本类型 | Java类 | Scala类型 | 说明 | 
|---|---|---|---|
| byte | Byte | Byte | -128~127 | 
| short | Short | Short | -32,768~32,767 | 
| int | Int | Int | -2,147,483,648~2,147,483,647 | 
| long | Long | Long | -9,223,372,036,854,775,808~9,223,372,036,854,775,807 | 
| float | Float | Float | IEEE定义的32位浮点数 | 
| double | Double | Double | IEEE定义的64位浮点数 | 
| char | Character | Char | 一个Unicode字符 | 
| boolean | Boolean | Boolean | true或者false | 
特殊类型
Scala中有几个特殊的类型:Any,AnyVal,AnyRef,Unit,Nothing,Null。
Any表示任意类型,它是所有类型的父类。
AnyVal表示值类型,它的构造函数有一个参数,Scala编译器对其做了一些特殊处理。
AnyRef表示所有引用类型,也就是除了继承了AnyVal的类以外的所有类的父类,类似于Java中的Object。
Unit表示无类型,类似于Java中的void,但是在Scala中,可以定义Unit类型的变量。Unit类型是单值类型(比较:Boolean类型是双值类型,有true和false两个取值)。
Nothing是所有类型的子类,基本上只用来作为泛型的参数。
Null是所有引用类型的子类,有一种值null。
元组
Scala中有一类类型称为元组(Tuple),实际上和其他类无异,但Scala为其定义了特殊的语法,所以在此说明。元组的类型表示是用()包含的一系列类型,值是用()包含的一系列表达式。除了长度为1的元组必须要用Tuple1声明以外,其他类型的元组都可以使用()表示。
| 1 2 3 | val a: Tuple1[Int] = Tuple1(1) val b: (Int, Int) = (1, 2) val c: (Int, Int, Int) = (1, 2, 3) | 
元组的用法在之后会说到。
方法
Scala中方法也是对象,所以也有一个类型定义。大体格式为参数类型列表,=>,返回类型。比如:
| 1 2 | def methodA(a: Int, b: Double): String = a + " " + b val d: (Int, Double) => String = methodA | 
这样,变量d的值就是方法method了。
with关键字
使用with关键字可以构造出相当复杂的类型,比如:
| 1 | val v: Vec3 with Ordered[Vec3] = _ | 
这里使用了with关键字给出了一个限定祖先类和特征的一种类型。
类型的检查和转换
在Java中可以使用instanceof关键字检查类型,可以使用强制转换。Scala将这两个功能写成了方法形式:
| 1 2 3 | val a: Any = "abc" println(a.isInstanceOf[String])              // true println(a.asInstanceOf[String].substring(1)) // bc | 
值得注意的一点是,asInstanceOf表示强制转换,也就是说,原本的对象应该是那个类型的子类,并不能将Int转化为Short。如果要做基本类型间降低精度的转换,可以使用to类型方法,比如:
| 1 2 | val b: Int = 1 val c: Double = b.toDouble | 
如果想要获得类型对应的对象,在Java里可以用类名.class的方式实现,而在Scala中是classOf[类名]:
| 1 | println(classOf[String]) // class java.lang.String | 
别名
用type关键字可以定义类型的别名,类似于C语言中的typedef:
| 1 2 3 4 5 6 7 8 9 10 | type IntList = List[Int] val l: IntList = List[Int]() def methodB(a: Int, b: Int): Unit = {   println(a)   println(b) } type Func2Unit = (Int, Int) => Unit val n: Func2Unit = methodB | 
获取变量的类型
用变量名.type可以获得变量的类型,特别的,用this.type可以获得本对象的类型。这种方法得到的类型可以用于定义其他变量或者函数参数或者返回值:
| 1 2 3 | val a: Int = 1 val b: a.type = a val c: this.type = this | 
注意区别.getClass和.type,前者是一个方法,可以获得类型对应的对象,后者是语法结构,用来表示某个变量的类型。
单例对象的类型也可以用这种方式获得:
| 1 2 | object AObject val o: AObject.type = AObject | 
总结
Scala的类型系统相比Java要复杂一些,并且为一些类型提供了新语法,这提高了Scala的简洁性,也使它变得难于学习。