Scala与Java具有许多相似之处,但又有许多不同。这里主要从一个Java开发人员的角度,总结在使用Scala的过程中所面临的一些思维转变。这里只是总结了部分两种语言在开发过程中的不同,以后会陆续更新一些切换后在开发过程中值得注意的地方。下面列举了部分,但令人印象深刻的Scala语言的不同之处,具体的代码示例及详细阐述见下文。
Scala中可直接调用Java代码,与Java无缝连接;
语句可以不用“;”结束,且推荐不适用“;”;
变量声明时以var或val开头,可不必指定变量类型,编译器可推断变量类型;
函数可以不定义返回值类型(特殊情况除外);
函数返回值可不用return返回;
无参函数定义及调用时,函数名后可不跟括号;
数组访问下标使用括号,而不用中括号;
元组使用“._n”的方式访问元素,n从1开始;
……。
指定Main函数
在Java中运行程序,只要指定入口的Main函数即可。一个工程中可以有多个Main函数,每个类内都可以定义Main函数。但是与Java不同的是,Scala工程中,只有定义在object中的Main函数才能作为程序入口,下图中定义在class中的Main函数是无法作为程序入口的。
要想程序能够执行,需要如下图所示,将Main函数定义在object中。在Scala中,class同Java中的类一样,但是Scala中没有static类型的类,与此同时,Scala中提供了一种object的定义方式,通过这种方式定义的“类”类似于Java中的static类,使用时不需要new相应的对象,直接使用外面能访问的变量和函数。object中定义的方法也类似于static方法,直接通过object名访问。
变量和字段声明
与Java中定义变量不同,在Scala中变量是通过“var|val 变量名 [: 类型] = 值”这种方式声明和定义的。在声明字段的时候,可以使用编译器自动推断类型,即不用写“ : 类型”,比如
var i : Int = 2;
或直接
var i = 2;1
2
3
var和val的区别是:var声明的变量的值之后还可以改变,而val声明的变量只能在声明时赋值,之后不能改变该变量的值(类似只读变量,但不是常量)。Scala的函数式编程更推荐使用val。
类的定义及不同
如下图所示,在Scala中也是通过class关键字定义类,看起来与Java中类似。在Scala类中默认的访问符是public,如果不明确的写明private或其他访问符,则类里的成员默认都是可以公开访问的。
但是Scala在构造函数方面与Java存在许多不同,Scala类中包括主构造器和附属构造器。Scala中类的主构造器:主构造器直接跟在类名后面,主构造器中的参数会被编译成类的字段;主构造器执行的时候会执行类中的所有不包含在方法体中的语句;如果在主构造器函数的参数中没有用val或者var去声明变量,那此时的变量是private[this]级别的,只能够被类内部访问。Person类的主构造器如下图所示,主构造器中的参数name和age会被作为Person类的两个成员变量,未被包含在任何方法内部的打印语句会作为主构造器中的语句被执行。
由于上图中定义的age没有使用val或var修饰,所以会被作为private类型的成员变量使用,这类变量只能在类内部访问。因此如下图所示,name能在类外部访问,而age不能被外部访问。
以上是主构造器的情况,Scala中还包括一类附属构造器,即除主构造器外的其他构造函数,附属构造器有以下特点:附属构造器是用this来声明的;附属构造器中必须调用主构造或者其它附属构造器。如下图所示为附属构造器的例子。
特别的函数定义
Scala中的函数定义与Java中有所区别,总体来说如下这种方式,返回值类型在参数列表后面通过“: 类型”这种方式指定,然后通过“=”承接函数体。对于无返回值类型的,类型可以写“Unit”(类似Java中的void),对于函数体简单的,“=”后面可直接接语句,不用“{}”。
与Java不同的是,语句块或函数返回值可以不用显示的通过“return”语句返回,一般块的最后一个表达式的值就是函数的返回值。因此上述函数可修改为下面的形式。
同变量声明不需要显示指定类型相同(变量可以推断变量类型),所以函数也可以推断返回类型,因此可以简写成如下所示:
然而,需要注意的是:如果函数使用return返回,那么必须明确指定函数的返回类型;此外如果是递归函数,也需要指定返回类型。下图所示为通过“return”返回的函数,函数定义时没有指定返回类型,编译器报错。
对于函数参数列表为空的,定义时函数名后可以不跟“()”,使用时也可以不跟“()”,如下图所示:
数组及元组的使用
两种数组定义如下图所示,与Java不同的是需要用到Array关键字。同Java中一样,数组长度不可变,数组元素可变。
Scala中数组通过下标对元素访问的方式如下图所示,主要通过2种方式,第一种是通过“arr(i)”这种方式,与Java中不同,Java中主要通过“arr[i]”这种方式访问。这是因为在Scala中,任何操作符都是函数调用的方式进行的。此外还提供了“arr.apply(i)”这种访问方式。
数组赋值和修改可通过下面两种方式进行,第一种适合代码显示赋值和修改,第二种适合程序运行阶段根据条件对特定元素赋值和修改。
对于数组的遍历可通过以下2种方式。其中第一种注意for循环的to也会取到;第二种遍历方式是通过foreach的方式传递匿名函数,如果数组元素需要指定类型,需要用“(item : String)”括号括起来,如果处理代码较复杂,可用“{}”语句块表示。
Scala中元组的定义和元素访问如下所示,定义时直接使用“()”将不同的类型的若干变量或字面值包围起来即可。值得注意的是,对于元组元素通过“._n”的方式进行访问,且n从1开始计数。
参考