在 Scala 中,所有的值都有类型,包括数值和函数。下面这个图表说明了类型继承结构的子集。
Scala 类型继承结构 (Scala Type Hierarchy)
Any
是所有类型的父类,也被叫成顶层类型。它定义了几个最普通的方法,比如 equals
,hashCode
,toString
。Any
有两个直接子类 AnyVal
和 AnyRef
。
AnyVal
代表值类型。一共有九种预定义值类型并且是非空的:Double
,Float
,Long
,Int
,Short
,Byte
,Char
,Unit
和 Boolean
。Unit
是一种值类型表示没有意义的值。Unit
类型只有一个值,被声明为:()
。所有的函数都必须有返回值,所以有时 Unit
是一种有用的返回值。
AnyRef
代表引用类型。所有的非值类型都被定义为引用类型。每个用户自定义类型在 Scala 中都是 AnyRef
的子类。如果 Scala 被用在 Java 运行环境的上下文中,AnyRef
对应的就是 java.lang.Object
。
这里的一个例子演示了像字符串,整数,字符,布尔值,和函数都是 Any
类型的子类。
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
常量,类型为:List[Any]
。这个列表使用各种类型的元素进行初始化,但是所有的元素都是 scala.Any
的实例,所以你才能把它们加入到列表中。
这里中上面的程序的输出结果:
a string
732
c
true
<function>
类型转换 (Type Casting)
值类型可以根据下图的方向进行转换:
例如:
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 // 不能通过编译
你也可以将一个引用类型转换成其子类型。这将会在之后讨论。
什么都没有与空(Nothing and Null)
Nothing
是所有类型的子类型,也被叫做底层类型。没有任何一个值的类型应该为Nothing
。一个通常的使用是作为一个非正常结束的信号,例如,抛出一个异常,程序手动退出,或者一个无限循环。(它是一个无法返回值的表达式的类型,或者没有正常返回值的方法的类型)[2]
Null
是所有引用类型的子类(任何 AnyRef 子类)。它只有一个值被定义为关键字 null
。Null
被提供给大部分其它 JVM 语言进行互通并且应该几乎不在 Scala 代码中使用。在之后我们将使用 null
。
网友评论