Scala作为基于jvm的语言,可以直接复用所有java的库资源,同时其具备函数式编程的特性以及脚本语言的特性,语法更加简洁。scala具备面向对象和函数式编程理念的混合体(这点和python有点像),从编写简单脚本到建立大型的系统,都是适用的。目前spark、kafaka等流行的大数据处理的软件都是由scala编写。
1 语法差异罗列
下面介绍一些scala语言和java语言差异点,通过简单罗列的方式讲述,详细语法建议找个系统性参考书或语法指南看下。
1、 scala可以编写脚本,编写一个.scala的脚本代码,直接用同scala x.scala进行执行。
但同时scala也可以类似java,通过scalac编译为.class等形式,基于编译执行。
2、 scala可以在交互式的命令中直接编码运行。
3、 支持隐式变量定义,通过var关键词定义一个变量,具体变量类型在赋值后,scala自行进行类型推断。例如var a = List(1,2,3)
4、 常量定义用val 关键词定义
5、 没有静态类型,通过object 定义单例类,main方法就是放在object类型中。如下就是简单的hello world
object MyMain {
def main(args: Array[String]): Unit = {
println("hello world!")
}
}
6、 没有java中原生类型,例如 int、float,所有类型都是引用类型,即例如只有Int、Float
7、 语法行后面的分号是可选的,可以省略
8、 空类型为Unit,对应于Java中的void
9、 所有类型默认引入单例类的Predef的方法,Predef包含了常用函数,例如println,这些方法可以直接在类中使用。
任何类型都默认引入了java.lang、scala、Predef
import java.lang._ // in JVM projects, or system namespace in .NET
import scala._ // everything in the scala package
import Predef._ // everything in the Predef objec
10、 通用的匹配符为_,对应Java中*。参考9中包引入的样例
11、 递增++操作符在scala中是不生效的
12、 Scala中== 等效于Java中的Equal,同时支持引用以及实际内容的比较。
Scala纯粹的引用比较有新的关键词 eq 和ne
13、 所有的操作符都是方法调用,都映射为特定方法调用
14、 语法上支持很多省略的写法,例如
1) 当调用无参数时,空括号()可以省略
2) 当调用对象的无参数方法时, . 以及() 都可以省略。
例如: List(1,2,3).size()写成 List(1,2,3)size
3) 分号省略也是一种
4) 类中的无参函数定义
class Complex(real: Double, imaginary: Double) {
def re = real
def im = imaginary
}
各种语法都存在很多简要和省略。后面也会继续介绍一些
15、 控制结构可以返回值,控制结构(例如if else、 match等)可用用于赋值。例如
var a = if( b >1)0 ; else 1
16、 数字序列语法to、 until
例如2 to 10,表示会2到10之间的数字,如不希望包括10,则可用 2 until 10
17、 match分支匹配关键字,对应于Java中的switch,但是可以支持任意的类型。同时可以返回值。
18、 控制语句的条件判断表达式部分,可以用花括号{}代替(),基于最后语句默认赋值的特征,在其中可以添加复杂多条语句。
19、 for语法不一样,有<-的特殊符号,示例如下:
for( a <-List(1,2,3)) println(a)
20、 for循环在scala中除了以上常规的循环外,还有多重功能
1) 嵌入 if语句,可以过滤,例如下面例子,过滤出偶数
for( a <-List(1,2,3,4) if a %2 ==0) println(a)
2) 多层嵌套, 无需再添加for, 直接嵌套
3) yield语法,可以产生新的集合
var b = for { a <-List(1,2,3,4) if a%2 == 0} yield a
21、 不支持break、continue的语法
22、 函数定义结构和Java存在较大差异
1) 函数使用def 开头
2) 返回值的类型是在函数声明后面
3) 函数参数定义的类型是在变量后面
4) 返回值不需要return,最后一个值就可以做为返回值。
5) 所有的函数参数都val 不可变类型,不可以修改
6) 函数体 前面有 =
以下为一个函数定义样例
def test(a:String, b:Int):String =
{
var c = b + 1
a + b
}
23、 函数字面量以及简短格式。
1) 函数可以作为变量
var increase = (x:Int) => x +1
increase(10)
2) 函数字面量的简单格式 ,例如传入filter函数中的短格式
List(1,2,3,4).filter(x => x% 2==0)
3)函数字面的占位符语法_,更简短格式
List(1,2,3,4).filter(_% 2 ==0)
这些语法形式在Java 8也已经有了类似lambda 形式
24、 函数变量以及匿名函数
(a:Int)=> 形式来定义函数变量
object Timer {
def oncePerSecond(callback: () => Unit) {
while (true) { callback(); Thread sleep 1000 }
}
def timeFlies() {
println("time flies like an arrow...")
}
def main(args: Array[String]) {
oncePerSecond(timeFlies)
}
}
还可以通过 () =>xx 直接定义匿名函数
oncePerSecond(() =>println("time flies like an arrow..."))
25、 类中 public 在scala中为默认属性级别,可以不加
26、 泛型的括号为[] ,而Java中为<>
例如Array[Int]
27、 集合索引使用(),而Java中为[]
例如 List(1,2,3)(0)
28、 数组为一个单独类型Array
29、 List在scala中默认为一个不可变的集合类型
30、 集合类支持很便捷的数据处理方式,(这个和Java 8 lambda语法类似)
31、 以List 为例介绍特有用法,
1)::: 连接多个List
2):: 连接值和List
3)符合条件的奇数 count(s => s % 2 ==0)
4) exists(条件)、 filter(条件)、
5)foreah(遍历函数)
6) map 转换
用法非常丰富,详见的api文档
7)alist sort (_ < _)
32、 有元祖的概念,var a = (2,3)
33、 Set、Map默认都为不可变,可以通过import定义为可变
Importscala.collection.mutable.Set
34、 trait 、Actor并发编程等高级概念
以上罗列一些scala的常见语法和Java差异,但还有很多其他差异这里没有包括。
2 总结
总体而言,和Java的语法相比,scala有很多简约的语法形式,而且很多相似功能语法也独立特行用自己个性化方式定义。个人感觉,scala的语法门槛比较高,没有python以及java的语法友好,有很多geek式的高级简洁用法。如果是进行spark等数据处理等应用层的程序开发,spark同时也支持python和Java接口,如果是已经熟悉python语法或Java语法,可以自行评估下是否要新学一门这样门槛相对高的语言。
3 推荐几个不错scala语法的讲解文档