什么是Scala?
Scala是一种多范式的编程语言,其设计的初衷是要集成面向对象编程和函数式编程的各种特性。Scala运行于Java平台(Java虚拟机),并兼容现有的Java程序。
为什么要学Scala
【1】优雅:
这是框架设计师第一个要考虑的问题,框架的用户是应用开发程序员,API是否优雅直接影响用户体验。
【2】速度快:
Scala语言表达能力强,一行代码抵得上Java多行,开发速度快;Scala是静态编译的,所以和JRuby,Groovy比起来速度会快很多。
【3】能融合到Hadoop生态圈:
Hadoop现在是大数据事实标准,Spark并不是要取代Hadoop,而是要完善Hadoop生态。JVM语言大部分可能会想到Java,但Java做出来的API太丑,或者想实现一个优雅的API太费劲。
安装Scala编辑器
一、安装JavaJDK
因为Scala是运行在JVM平台上的,所以安装Scala之前要安装JDK,这里默认大家已经全部安装好!
二、安装Scala编辑器
(1)Windows安装Scala编译器
访问Scala官网http://www.scala-lang.org/下载Scala编译器安装包,目前最新版本是2.13.x,下载scala-2.13.1.msi后,点击下一步就可以了
https://www.scala-lang.org/download/
(2)Linux安装Scala编译器
【1】红帽系列RPM包--tgz绿色版
下载Scala地址http://downloads.typesafe.com/scala/2.13.1/scala-2.13.1.tgz然后解压Scala到指定目录
tar -zxvf scala-2.13.1.tgz -C /usr/java
配置环境变量,将scala加入到PATH中
vi /etc/profile
export JAVA_HOME=/usr/java/jdk1.8.0_221
export PATH=$PATH:$JAVA_HOME/bin:/usr/java/scala-2.13.1/bin
【2】红帽系列RPM包--RPM安装版
rpm -ivh scala-2.13.1.rpm
默认情况下,安装版的编译器会自动的添加到系统的运行环境中;
【3】Debian系列deb包--安装版
在download中找到下载的scala-2.13.1.deb,双击进行安装,
默认情况下,安装版的编译器会自动的添加到系统的运行环境中;
【4】打开命令行验证是否安装成功,笔者以Linux Debian为例;
在命令行中键入 scala,出现下图效果,直接进入命令行,注意,这里按Ctrl + C退出
(3)Scala的使用
编写Scala程序可以直接使用命令行窗口,但那是只有在原始社会才会那样干,目前最流行开发工具为IntelliJ IDEA 或者是 Eclipse ,本文笔者使用IDEA开发Scala,笔者的开发环境为Linux Deepin15.11 版本,IDEA版本为2019.1.3;
【1】首先配置Scala编译器的环境
打开IDEA,在开始业,选择插件(plugins)
在搜索框中搜索Scala
安装后查看
【2】在工程中引入Scala
创建一个普通的Java工程
寻找本地的SDK,注意选择到安装位置的根目录即可;
验证,在Java下新建一个包,在包上新建,查看是否有Scala class选项
(4)Scala的第一个入门程序 Hello.scala
选择一个Scala class ,创建一个Object类型的类,类名为 HelloObjectDemo
object HelloObjectDemo {
def main(args: Array[String]): Unit = {
var hello = "Hello Scala"
println(hello)
}
}
定义变量
object HelloObjectDemo {
def main(args: Array[String]): Unit = {
//使用var定义一个可变的变量
var variable = "Hello Scala"
//对于普通数值数据类型,用var 定义的变量可以改变
variable = "Hello everything"
//对于引用数据类型,var定义的变量还可以重新指向一个新的内存地址
//使用val定义一个不可变的变量
//对于普通数值数据类型,用val 定义的变量不可以改变
//对于引用数据类型,val定义的变量不可以重新指向一个新的内存地址
//但是指向的内存地址对应的对象的属性可以改变
val value = "Hello java"
}
}
常用类型
Scala和Java一样,有8种数据类型: 7种数值类型Byte、Char、Short、Int、Long、Float和Double(无包装类型)和一个Boolean类型
Boolean | true 或者 false |
---|---|
Byte | 8位, 有符号 |
Short | 16位, 有符号 |
Int | 32位, 有符号 |
Long | 64位, 有符号 |
Char | 16位, 无符号 |
Float | 32位, 单精度浮点数 |
Double | 64位, 双精度浮点数 |
String | 其实就是由Char数组组成 |
与Java中的数据类型不同,Scala并不区分基本类型和引用类型,所以这些类型都是对象,可以调用相对应的方法。
常用类型结构图
Scala中,所有的值都是类对象,而所有的类,包括值类型,都最终继承自一个统一的根类型Any。统一类型,是Scala的又一大特点。更特别的是,Scala中还定义了几个底层类(Bottom Class),比如Null和Nothing。
1)Null
所有引用类型AnyRef的子类型,而Nothing是所有类型的子类型。Null类只有一个实例对象,null,类似于Java中的null引用。null可以赋值给任意引用类型,但是不能赋值给值类型。
Null是所有AnyRef的子类,在scala的类型系统中,AnyRef是Any的子类,同时Any子类的还有AnyVal。对应java值类型的所有类型都是AnyVal的子类。所以Null可以赋值给所有的引用类型(AnyRef),不能赋值给值类型,这个java的语义是相同的。 null是Null的唯一对象。
2)Nothing
可以作为没有正常返回值的方法的返回类型,非常直观的告诉你这个方法不会正常返回,而且由于Nothing是其他任意类型的子类,他还能跟要求返回值的方法兼容。
Nothing是所有类型的子类,也是Null的子类。Nothing没有对象,但是可以用来定义类型。例如,如果一个方法抛出异常,则异常的返回值类型就是Nothing(虽然不会返回)
3)Unit类型
用来标识过程,也就是没有明确返回值的函数。 由此可见,Unit类似于Java里的void。Unit只有一个实例,(),这个实例也没有实质的意义。
在scala中,Any类是所有类的超类,Any有两个子类:AnyVal和AnyRef。对应Java直接类型的scala封装类,如Int、Double等,AnyVal是它们的基类;对应引用类型,AnyRef是它们的基类。
算数操作符重载
+-*/%可以完成和Java中相同的工作,但是有一点区别,他们都是方法。你几乎可以用任何符号来为方法命名。
1 + 2
等同于:
1.+(2)
1*2
等同于:
1.*2
...
//Scala中没有++、--操作符,需要通过+=、-=来实现同样的效果。
条件表达式
//注意1:条件表达式会返回一个结果,如果没有匹配到结果,会返回unit的实例()
//注意2:条件表达式允许返回不同类型的数据,返回值的数据类型为any
if(条件表达式){
语句1;
}
if(条件表达式1){
语句1;
}else{
语句2;
}
if(条件表达式1){
语句1;
}else(条件表达式2){
语句2;
}else{
...
}
/*
特别提醒:
【1】scala中没有三目运算符,因为根本不需要。
【2】行尾的位置不需要分号,只要能够从上下文判断出语句的终止即可。
但是如果在单行中写多个语句,则需要分号分割。
*/
块表达式
在Scala中,{}快包含一系列表达式,其结果也是一个表达式。块中最后一个表达式的值就是块的值。
{
语句1;
语句2;
语句3;
...
语句xx//该语句为块表达式的结果,主要用于函数的返回值
}
循环结构
Scala中有三种循环结构,分别是while,do ... while ,for,其中,while 与do ... while 与Java中的用法相同;
(1)while
//打印1~10
var n = 1
while(n <= 10){
println("n = "+n)
n+=1
}
/*
特别提示:
scala并没有提供break和continue语句来退出循环,
如果需要break,可以通过以下几种方法来做
1、使用Boolean型的控制变量
2、使用嵌套函数,从函数中return
3、使用Breaks对象的break方法。
*/
(2)do ... while
//打印1~10
var n = 1
do{
println("n = "+n)
n+=1
}while(n <= 10 )
(3)for
//打印1~10
//for的语法 for(i <- Range或者集合)
//方式1
//to 的用法为闭区间
for(i <- 1 to 10){
println("i = "+i)
}
//方式2
//util 的方式
//方式3
//Range 的三个参数为(起始值,结束值,步长【可正可负】)
for(i <- Range(1,10,1)){
println("i = "+i)
}