一、操作符在Scala里的解释
在诸如C++、Java等oop语言里,定义了像byte、short、int、char、float之类的基本类型,但是这些基本类型不属于面向对象的范畴。就好比C语言也有这些类型,但是C语言根本没有面向对象的概念。 比如只能说“1”是一个int类型的常量,却不能说它是一个int类型的对象。与之对应的,这些语言还定义了与基本类型相关的操作符。例如,有算术操作符加法“+”,它可以连接左、右两个操作数,然后算出相应的总和。
前面提到,Scala追求纯粹的面向对象,像这种不属于面向对象范畴的基本类型及其操作符都是有违宗旨的。那么,Scala如何实现这些基本类型呢?实际在Scala标准库里定义了“class Byte”、“class Short”、“class Char”、“class Int”、“class Long”、“class Float”、“class Double”、“class Boolean”和“class Unit”九种值类,只不过这些类是抽象的、不可继承的,因此不能通过“new Int”这种语句来构造一个Int对象,也不能编写它们的子类,它们的对象都是由字面量来表示。例如,整数字面量“1”就是一个Int的对象。在运行时,前八种值类会被转换成对应的Java基本类型。第九个Unit类对应Java的“void”类型,即表示空值,这样就能理解返回值类型为Unit的、有副作用的函数其实是空函数。Unit类的对象由一个空括号作为字面量来表示。
简而言之,Scala做到了真正的“万物皆对象”。
还有,与基本类型相关的操作符该如何处理呢?严格来讲,Scala并不存在操作符的概念,这些所谓的操作符,例如算术运算的加减乘除,逻辑运算的与或非,比较运算的大于小于等等,其实都是定义在“class Int”、“class Double”等类里的成员方法。也就是说,在Scala里,操作符即方法。例如,Int类定义了一个名为“+”的方法,那么表达式“1 + 2”的真正形式应该是“1.+(2)”。它的释义是:Int对象“1”调用了它的成员方法“+”,并把Int对象“2”当作参数传递给了该方法,最后这个方法会返回一个新的Int对象“3”。
推而广之,“操作符即方法”的概念不仅仅限于九种值类的操作符,Scala里任何类定义的成员方法都是操作符,而且方法调用都能写成操作符的形式:去掉句点符号,并且方法参数只有一个时可以省略圆括号。例如:
scala> class Students3(val name: String, var score: Int) {
| def exam(s: Int) = score = s
| def friends(n: String, s: Int) = println("My friend " + n + " gets " + s + ".")
| override def toString = name + "'s score is " + score + "."
| }
defined class Students3scala> val stu3 = new Students3("Alice", 80)
stu3: Students3 = Alice's score is 80.scala> stu3 exam 100
scala> stu3.score
res0: Int = 100scala> stu3 friends ("Bob", 70)
My friend Bob gets 70.
二、三种操作符
Ⅰ、前缀操作符
写在操作数前面的操作符称为前缀操作符,并且操作数只有一个。前缀操作符对应一个无参方