文章目录
一、简介
1.1 scala语言的特点
1.2 第一个scala程序
二、变量
2.1 Scala变量的使用
2.2 Scala数据类型
2.3 值类型转换
三、循环控制
3.1 分支控制if-else
3.2 for循环控制
Spark—新一代内存级大数据计算框架,是大数据处理的重要框架。Spark就是使用Scala编写的。因此为了更好的学习Spark,需要掌握Scala这门语言
一、简介
1.1 scala语言的特点
Scala是一门以JVM为目标运行环境并将面向对象和函数式编程的最佳特性结合在一起的静态类型编程语言
Scala是一门多范式的编程语言,支持面向对象和函数式编程
Scala可以说是源于Java,Scala源代码会被编译成Java字节码,然后运行于JVM之上,并可以调用现有的Java类库,实现两种语言的无缝对接
Scala方法由一条条语句构成,每个语句后不需要分号
Scala简洁高效
1.2 第一个scala程序
object Hello {
def main(args: Array[String]): Unit = {
println(“Hello World”)
}
}
说明:
scala在编译源码时,会生成两个字节码文件,静态main方法执行另一个字节码文件中成员main方法。
scala是完全面向对象的语言,没有静态语法,只能通过模拟生成静态方法
Hello$类的对象称之为“伴生对象”。伴生对象中的内容,都可以通过类名访问来模拟java中的静态语法。伴生对象的语法规则:使用object声明。
在这里插入图片描述
另外:
scala中没有public关键字,默认所有的访问权限都是公共的;scala中没有void关键字,采用特殊的对象模拟:Unit;scala中声明方法采用关键字def。
scala中参数列表的声明方式和java不一样。java : 类型参数名;scala:参数名:类型。
java中方法的声明和方法体直接连接;scala中方法的声明和方法体是通过等号连接。
scala中将方法的返回值类型放置在方法声明的后面使用冒号连接。
二、变量
2.1 Scala变量的使用
变量声明基本语法:var | val 变量名 [: 变量类型] = 变量值,例:var num:Int=1
注意事项:
变量声明时,必须有初始值(显示初始化)
声明变量时,类型可以省略(类型推断)。类型确定后,就不能修改,说明Scala 是强数据类型语言
在声明变量时,可以使用var或者val来修饰,var修饰的变量可改变;val修饰的变量不可改变,相当于java中使用了final修饰
var修饰的引用可以改变,val修饰则不可改变,但对象的状态(值)却是可以改变的。(比如: 自定义对象、数组、集合等等)
2.2 Scala数据类型
scala数据类型分为两大类AnyVal(值类型) 和AnyRef(引用类型), 注意:不管是AnyVal还是AnyRef都是对象。
在这里插入图片描述
Unit表示无值,和其他语言中void等同。用作不返回任何结果的方法的结果类型。Unit只有一个实例值,写成()
Nothing类型在scala的类层级的最低端;它是任何其他类型的子类型
AnyRef类是scala里所有引用类(reference class)的基类
① 整型
数据类型 描述
Byte 8位有符号补码整数。数值区间为 -128 到 127
Short 16位有符号补码整数。数值区间为 -32768 到 32767
Int 32位有符号补码整数。数值区间为 -2147483648 到 2147483647
Long 64位有符号补码整数。数值区间为 -9223372036854775808 到 9223372036854775807 = 2的(64-1)次方-1
scala各整数类型有固定的表数范围和字段长度,不受具体OS的影响,以保证scala程序的可移植性
scala的整型默认为Int型,声明Long型变量后加l或L
② 浮点类型
数据类型 描述
Float 32 位, IEEE 754标准的单精度浮点数
Double 64 位, IEEE 754标准的双精度浮点数
与整数类型类似,scala浮点类型也有固定的表数范围和字段长度,不受具体OS的影响
scala的浮点型常量默认为Double型,声明Float后后加f或F
③ 字符类型(Char)
字符类型可以表示单个字符,字符类型是Char, 16位无符号Unicode字符(2个字节),区间值为 U+0000到U+FFFF。
字符常量是用单引号(‘ ’)括起来的单个字符。例如:var c1 = 'a‘
scala也允许使用转义字符\来将其后的字符转变为特殊字符型常量。例如:var c3 = ‘\n’
可以直接给Char赋一个整数,然后输出时,会按照对应的unicode字符
Char类型是可以进行运算的,相当于一个整数
④ 布尔类型
Boolean类型数据只允许取值true和false,只占1个字节。
⑤ Unit、Nul和Nothing
数据类型 描述
Unit 表示无值,和其他语言中void等同。用作不返回任何结果的方法的结果类型。Unit只有一个实例值,写成()
Null Null 类型只有一个实例值 null
Nothing Nothing类型在Scala的类层级的最低端;它是任何其他类型的子类型。当一个函数,我们确定没有正常的返回值,可以用Nothing 来指定返回类型,这样有一个好处,就是我们可以把返回的值(异常)赋给其它的函数或者变量(兼容性)def f1():Nothing = { throw new Exception()}
Null类只有一个实例对象null,类似于java中的null引用。null可以赋值给任意引用类型AnyRef,但是不能赋值给值类型AnyVal
Unit类型用来标识过程,也就是没有明确返回值的函数。由此可见,Unit类似于java里的void。Unit只有一个实例(),这个实例也没有实质的意义
Nothing可以作为没有正常返回值的方法的返回类型,非常直观的告诉你这个方法不会正常返回,而且由于Nothing是其他任意类型的子类,他还能跟要求返回值的方法兼容
2.3 值类型转换
当scala程序在进行赋值或者运算时,精度小的类型自动转换为精度大的数据类型,这个就是自动类型转换(隐式转换 )。scala还提供了非常强大的隐式转换机制(隐式函数,隐式类,隐式值,implicity等等)。
自动类型转换细节说明:
有多种类型的数据混合运算时,系统首先自动将所有数据转换成容量最大的那种数据类型,然后再进行计算
当我们把精度(容量)大 的数据类型赋值给精度(容量)小 的数据类型时,就会报错,反之就会进行自动类型转换
(byte、 short) 和char之间不会相互自动转换
byte、short、char 他们三者可以计算,在计算时首先转换为int类型
自动提升原则: 表达式结果的类型自动提升为操作数中最大的类型
强制类型转换:自动类型转换的逆过程,将容量大的数据类型转换为容量小的数据类型。使用时要加上强制转函数,但可能造成精度降低或溢出,格外要注意
三、循环控制
3.1 分支控制if-else
注意事项:
如果大括号{}内的逻辑代码只有一行,大括号可以省略
scala中任意表达式都是有返回值的,也就意味着if-else表达式其实是有返回结果的,具体返回结果的值取决于满足条件的代码体的最后一行内容
scala中是没有三元运算符,可以这样简写:val result = if (flg) 1 else 0
3.2 for循环控制
scala也为for循环控制结构提供了非常多的特性
语法①
for (i <- 1 to 3) {
println(i)//1 2 3 前后闭合
}
语法②
for (i <- 1 to 3) {
println(i)//1 2 前闭合后开
}
循环守卫:
即循环保护式,保护式为true则进入循环体内部,为false则跳过,类似continue
for (i <- 1 to 3 if i != 2) {
println(i) //1 3
}
引入变量:
范围后一定要加;来隔断逻辑
for (i <- 1 to 3; j = 1) {
println(i + j)//2 3 4
}
嵌套循环:
范围后一定要加;来隔断逻辑
for (i <- 1 to 2; j <- 1 to 2) {
println(i + "->" + j)//1->1 1->2 2->1 2->2
}
等价于:
for (i <- 1 to 2) {
for (j <- 1 to 2) {
println(i + "->" + j) //1->1 1->2 2->1 2->2
}
}
循环返回值:
默认情况下for循环的返回值都是();使用yield关键字可以将每次循环的返回值放到一个Vector集合中。
val unit:Unit=for (i <- 1 to 2){
i
}
println(unit)//()
val res = for (i <- 1 to 2) yield i * 2
println(res)//Vector(2, 4)
步长控制:
/**
* scala实现打印杨辉三角
* Range函数:前闭合后开,第三位为步长
*/
for (i <- Range(1, 18, 2)) {
println(" " * ((18 - i) / 2) + "*" * i)
}
中断循环:
import scala.util.control.Breaks
var sum: Int = 0
Breaks.breakable {
for (i <- 1 to 5) {
if (i == 3) {
Breaks.break()
}
sum += i
println(i) //1 2
}
}
println(sum) //3
可简写为:
import scala.util.control.Breaks._
var sum: Int = 0
breakable {
for (i <- 1 to 5) {
if (i == 3) {
break()
}
sum += i
println(i) //1 2
}
}
println(sum) //3
异常:
try {
val r = 10 / 0
} catch {
case ex: ArithmeticException=> println("捕获了除数为零的算术异常")
case ex: Exception => println("捕获了异常")
} finally {
// 最终要执行的代码
println("scala finally...")
}
scala没有编译异常这个概念,异常都是在运行的时候捕获处理
用throw关键字,抛出一个异常对象。所有异常都是Throwable的子类型。throw表达式是有类型的,就是Nothing,因为Nothing是所有类型的子类型,所以throw表达式可以用在需要类型的地方
catch子句是按次序捕捉异常的
scala提供了throws关键字来声明异常
@throws(classOf[NumberFormatException])
def func() = {
“abc”.toInt
}
原文链接:https://blog.csdn.net/qq_38697437/article/details/108106078?utm_medium=distribute.pc_feed.none-task-blog-cf-2.nonecase&depth_1-utm_source=distribute.pc_feed.none-task-blog-cf-2.nonecase&request_id=5f43987dcea070620e93ee8c