scala 系列
scala 入门基础
前言
本篇博客为大家带来的是 scala 入门简介和编程基础,主要涉及scala 变量、分支和循环的基础知识,而关于数组、集合等scala 常用方法将在下一篇博客介绍。
相信大家在看完本篇博客后,都够对 scala 有个初步的认识!
思维导图
scala 简介
scala 源自 Java
scala是运行在 JVM 上的多范式编程语言,同时支持面向对象和面向函数编程。更重要的是scala 能够和 java 互通互融,可以访问庞大的Java类库,例如:操作mysql,redis,freemarker,activemq等等。
scala 的主要优势是它的 表达性 。没错,相比于 java 而言,scala可以用更少的代码"优雅"地表达出我们所想,就是说 scala 代码的飘逸。
scala 的优势
- 多范式编程:面向对象编程、函数式编程
- 面向对象编程
- 每个值都是对象
- 对象的数据类型和行为由类(Class)和 特质(Trait,类似于interface)描述
- 利用特征实现混入式多重继承
- 函数式编程
- 每个函数都是一个值
- 支持高阶函数、柯里化(currying)、样例类(case class)及模式匹配……
- Scala是静态类型语言
- 扩展性:隐式类、字符串插值
- 面向对象编程
- 表达能力强,代码精简,一行代码抵得上Java多行,开发速度快
- 大数据与 scala
- Spark 采用 scala 语言设计
- 提供的 API 更加优雅
- 基于 JVM 的语言更融入 Hadoop 生态圈
scala 与 java 对比实例
java 代码:
public class Studnet {
private Integer id;
private Integer classId;
private String name;
private String gender;
private Integer age;
private String province;
private String city;
private String district;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getClassId() {
return classId;
}
public void setClassId(Integer classId) {
this.classId = classId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getDistrict() {
return district;
}
public void setDistrict(String district) {
this.district = district;
}
}
scala代码:
case class Student(var id:Int, var classId:Int, var name:String, var gender:String, var age:Int, var province:String, var city:String, var district:String)
这个实例能够很明显的看出 scala 代码的精简和飘逸性。更多的我们将会在下一篇博客详解。
变量
声明变量
在scala中,可以使用 val 或者 var 来定义变量,语法格式如下:
val/var 变量标识:变量类型 = 初始值
注意
- val 定义的是不可重复赋值的变量,类似于 Java 中的 final 变量
- var 定义的是可重复赋值的变量,类似于 Java 中的普通变量
- scala中定义变量类型写在变量名后面
- scala的语句最后不需要添加分号,默认是隐式添加分号
- 优先使用 val 来定义变量,如果变量需要被重写赋值,才使用 var
使用类型推断来定义变量
scala可以自动根据变量的值来自动推断变量的类型,这样编写代码更加简洁:
scala> val a = 2
a: Int = 2
一般无需显示指定类型,Scala 编译器会自动推断 出其类型。
使用类型别名定义变量
使用关键字 type 定义类型别名
type 类型别名=类型
实例:
scala> type T = String
defined type alias T
scala> val name:T = "hubert"
name: T = hubert
惰性赋值
当有一些变量保存的数据较大时,但是不需要马上加载到JVM内存。可以使用惰性赋值来提高效率:
lazy val/var 变量名 = 表达式
在企业的大数据开发中,有时候会编写非常复杂的SQL语句,这些SQL语句可能有几百行甚至上千 行。这些SQL语句,如果直接加载到JVM中,会有很大的内存开销。如何解决?
例如:
scala> lazy val sql = """ insert overwrite table adm.itcast_adm_personas 19
| select
| a.user_id,
....
| left join gdm.itcast_gdm_user_buy_category c on a.user_id=c.user_id
| left join gdm.itcast_gdm_user_visit d on a.user_id=d.user_id; """
sql: String = <lazy>
字符串
使用双引号
语法:
val/var 变量名 = “字符串”
实例:
scala> val subject = "hadoop"
subject: String = hadoop
scala> println(subject+"\t"+subject.length)
hadoop 6
使用插值表达式
scala中,可以使用插值表达式来定义字符串,有效避免大量字符串的拼接。
语法:
//s插值器:允许将变量引用、表达式直接插入字面字符中
val/var 变量名 = s"${变量/表达式}字符串"
//f 插值器
val/var 变量名 = f"${变量/表达式}字符串"
// raw插值器:原样输出
val/var 变量名 = raw"${变量/表达式}字符串"
实例:
scala> val name = "hubert"
name: String = hubert
scala> val subject = "scala"
subject: String = scala
scala> val score = 96
score: Int = 96
scala> val info = s"name=${name},subject=${subject},score=${score}"
info: String = name=hubert,subject=scala,score=96
使用三引号
如果有大段的文本需要保存,就可以使用三引号来定义字符串。例如:保存一大段的SQL语句。三 个引号中间的所有字符串都将作为字符串的值。
语法:
val/var 变量名 = """字符串1
字符串2"""
实例:
scala> lazy val sql = """ insert overwrite table adm.itcast_adm_personas 19
| select
| a.user_id,
....
| left join gdm.itcast_gdm_user_buy_category c on a.user_id=c.user_id
| left join gdm.itcast_gdm_user_visit d on a.user_id=d.user_id; """
sql: String = <lazy>
数据类型
Scala与Java有着相同的原始数据类型
基础类型 | 类型说明 |
---|---|
Byte | 8位带符号整数。数值区间-128 ~ 127 |
Short | 16位带符号整数。数值区间-32768 ~ 32767 |
Int | 32位带符号整数。数值区间 -2147483648 ~ 2147483647 |
Long | 64位带符号整数。-9223372036854775808 ~ 9223372036854775807 |
Char | 16位无符号Unicode字符。区间值为U+0000 ~ U+FFFF |
String | Char类型的序列(字符串)。等于java.lang.String |
Float | 32位单精度浮点数 |
Double | 64位双精度浮点数 |
Boolean | true或false |
备注:
- scala 中所有的类型都使用大写字母开头
- 整形使用 Int 而不是 Inteage
- scala 中定义变量可以不写类型,让 scala 编译器自动推断
Scala数据类型层次结构
备注:
- Any:所有类型的超类(顶级类型),它有两个子类AnyRef与AnyVal
- AnyVal:表示值类型的超类
- AnyRef:表示引用类型的超类,对应java.lang.Object
- Unit:表示空,Unit是AnyVal的子类,它只有一个的实例() 它类似于Java中的void,但scala要比Java更加面向对象
- Nothing:所有类型的子类,表示空引用。 不能直接创建该类型实例,某个方法抛出异常时,返回的就是Nothing类型,因为 Nothing是所有类的子类,那么它可以赋值为任何类型
- Null:Null是AnyRef的子类,也就是说它是所有引用类型的子类,表示空值。它的实例是null 可以将null赋值给任何对象类型
两种常见问题:
-
问题一:
scala> val b:Int = null <console>:11: error: an expression of type Null is ineligible for implicit conversion val b:Int = null
Null类型并不能转换为Int类型,说明Null类型并不是Int类型的子类。
-
问题二:
scala> def m3(x:Int, y:Int):Int ={ | if(y==0) throw new Exception("这是一个异常") | x/y | } m3: (x: Int, y: Int)Int scala> def main(args: Array[String]): Unit = { | val c = m3(1,0) | } main: (args: Array[String])Unit
运算符
类别 | 操作符 |
---|---|
算术运算符 | +、-、*、/ |
关系运算符 | >、<、==、!=、>=、<= |
逻辑运算符 | &&、||、! |
位运算符 | &、||、^、<<、>> |
注意:
- scala 中没有,++、
--
运算符 - 与 Java 不一样,在 scala 中,可以直接使用 == 、 != 进行比较,它们与 equals 方法表示一致。而比较两个对象的引用值,使用 eq
实例:
scala> val a = "scala"
a: String = scala
scala> val b = a +""
b: String = scala
scala> a == b
res15: Boolean = true
scala> a eq b
res16: Boolean = false
分支表达式
分支表达式就是 if 表达式,if表达式可以根据给定的条件是否满足,根据条件的结果(真或假)决定 执行对应的操作。scala 条件表达式的语法和 Java 一样。
scala 与 java 分支的区别:
-
在scala中,条件表达式也是有返回值的。Scala 任何表达式都有返回值。
scala> val a = if(1>2) 3 else 4 a: Int = 4
-
在scala中,没有三元表达式,可以使用if表达式替代三元表达式
块表达式
-
代码块“{…}”也是表达式,返回值为最后一个表达式结果
scala> val y={ | print("我是代码块") | x+1 | } 我是代码块y: Int = 11 scala> val x=10 x: Int = 10 scala> val y={ | x+1;print("我是代码块") //多个表达式使用“;”分隔 | } 我是代码块y: Unit = ()
循环
在 scala 中,可以使用 fo r和 while ,但一般推荐使用 for 表达式,因为 for 表达式语法更简洁。scala 中的 while 和 do-while 循环和 java 一致。
for 循环
for (i <- 表达式、数组、集合){
表达式
}
简单循环实例:
// 简单写法
scala> for (i <- 1 to 10){
| println(i)
| }
// 中缀调用法
scala> for (i <- 1 to 10) println(i)
“i to j"或者"i until j"均表示创建一个区间 Range 。
嵌套循环:
// 使用for表达式打印3行,5列星星
scala> for (i <- 1 to 3; j <- 1 to 5) {print("*");if(j==5) println}
*****
*****
*****
scala> for (i <- 1 to 3){
| for(j <- 1 to 5){
| print("*")
| }
| println()
| }
*****
*****
*****
for守卫: for表达式中,可以添加if判断语句:
for (i <- 表达式/数组/集合 if 表达式){
表达式
}
实例:
// 打印1-10之间的偶数
scala> for (i <- 1 to 10 if (i%2==0)) println(i)
2
4
6
8
10
for 推导式:生成一个新的集合:
在for循环体中,可以使用yield表达式构建出一个集合,我们把使用yield的for表达式称之为推导。
// for 循环中的 yield 会把当前的元素记下来,保存在集合中,循环结束后将返回该集合。也称for推导式
scala> for (i <- 1 to 10 if (i%2==0)) yield i
res25: scala.collection.immutable.IndexedSeq[Int] = Vector(2, 4, 6, 8, 10)
while 循环 和 do -while 循环
scala 中的 while 和 do-while 循环和 java 一致。
while ( num < 100 ) {
| println( num );
| num = num + 1;
| }
scala> var num: Int = 0
num: Int = 0
scala> do {
| println( num );
| num = num + 5;
| } while ( num < 200 )
循环跳转语句
break 实现
- 导入Breaks包
import scala.util.control.Breaks._
- 使用breakable将for表达式包起来(可选)
- for表达式中需要退出循环的地方,添加break方法调用
实例:
scala> import scala.util.control.Breaks._
import scala.util.control.Breaks._
scala> for (i <- 1 to 10){
| if(i==6){
| break;
| }
| println(i)
| }
1
2
3
4
5
scala.util.control.BreakControl
continue 实现
实现break是用breakable{}将整个for表达式包起来,而实现continue是用breakable{}将for表达式的循环体包含起来就可以了。
实例:
scala> import scala.util.control.Breaks._
import scala.util.control.Breaks._
scala> for (i <- 1 to 10){
| breakable{
| if(i==6){
| break;
| }
| println(i)
| }
| }
1
2
3
4
5
7
8
9
10
本次分享就到这里,如果有不足之处,望指点!谢谢!