Scala和Java的语法差异

时间:2022-03-25 14:52:14

Scala和Java的语法差异

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语法的讲解文档

为Java程序员编写的Scala的入门教程

 scala基本语法及注意点