在Scala中,所有的值都有一个类型,包括数值和函数。下面的这张图阐释了类型的一个层次关系子集。
Scala类型层次结构
Any 是所有类型的父类型,也被称之为顶级类型。它里面定义的一些通用的方法,例如 equals,hashCode,和toString. Any 有两个直接的子类: AnyVal 和 AnyRef.
AnyVal 代表的是值类型。 Scala预定义了9个值类型,值类型是不可以为空的,包括: Double,Float,Long,Int,Short,Byte,Char,Unit 以及 Boolean . Unit 是一个没有任何有意义信息的值类型。Unit 实际上就是约等于 () 对象。因为所有函数都必须要有返回,所以Unit是一个非常有用的返回类型。
AnyRef 代表的是引用类型。所有的非值类型都会被定义为引用类型。 每一个用户自定义的类型在Scala中都是AnyRef的子类型。如果Scala在java 运行环境的上下文中其对标的是java.lang.Object。
如下的例子演示了 String,Integer,Char,Boolean值和函数都是对象,与其他的对象没有区别。
val list: List[Any] = List( "a string", 732, // an integer 'c', // a character true, // a boolean value () => "an anonymous function returning a string" ) list.foreach(element => println(element))
上面定义了一个类型为List[Any]的值 list。这个list 初始化了多个类型的节点,但是没有实例都是 Scala.Any 类型,所以可以添加到 list中去。
下面就是上面代码的输出结果:
a string 732 c true <function>
类型转换
值类型转换可以按照如下的方式进行
例如:
val x: Long = 987654321 val y: Float = x // 9.8765434E8 (note that some precision is lost in this case) val face: Char = '☺' val number: Int = face // 9786
转换是单向的,下面则不会被编译通过
val x: Long = 987654321 val y: Float = x // 9.8765434E8 val z: Long = y // Does not conform
当然也可以将引用类型强转为子类型。这个我们会在后面的章节介绍
Nothing和Null
Nothing 是所有类型的子类型,也被称之为底层类型。没有值是Nothing类型。一般的用途是用来标记一个非正常结束,例如抛异常,程序中断或者一个死循环(例如没有产生任何值的表达式,或者方法没有正常返回)
Null 是所有引用类型的子集(类似于的 AnyRef是Any的子集)。它在语法上等同于关键字null。Null 的主要作用是与JVM语言的交互性,在scala中应该尽量避免出现。后面的章节将会介绍null的替换方案。