Scala基础知识
一、环境搭建
scala环境搭建请参考 Scala环境搭建+IDEA插件安装及项目创建
二、特点
2.1、静态类型
Scala的变量声明后不允许改变类型,所有变量和表达式的类型在编译时就已经完全确定。
2.2、强类型
Scala在声明变量时一般无需显示指定类型,编译器会自动推断出类型。
Scala中没有强制类型转换,但有三种方法取代:
- 对象名.asInstanceOf[XXX]
- 对象名.toXXX方法
- 隐式转换(implicit 关键字)
2.3、多范式编程
- 面向对象特性
- Scala中一切值都是对象
- 使用伴生对象模拟类对象,去除了static关键字(Java中static修饰的静态属性和方法不是纯粹的对象)
- 没有接口,类和特质取而代之;利用特质实现混入式多重继承
-
函数式编程
一切函数都是值,所以可以把函数作为参数和返回值
三、数据类型
1.值类型(AnyVal)
(1)直接存储值,在栈上存储其值
(2)与Java的八大基本类型一致(Byte、Short、Int、Long、Float、Double、Char、Boolean)
2.引用类型(AnyRef)
(1)存储对其值的引用,在栈上存储地址,堆上存储值
(2)List、Option等,已经自定义类
3.字面量:直接在代码中写常量值的方式:0,0L等等;符号字面量:’<标识符>’,对应scala.Symbol类型
4.特殊类型:
(1)Null:所有引用类型的子类,只有一个实例对象null,并且null为关键字
(2)Nothing:List()返回是List[Nothing]
(3)Unit:仅有一个实例对象“()”,无用占位符,类似Java的void。一切表达式都有值
四、基本语法
4.1、常量与变量
变量:赋值后可以改变,生命周期中可以多次被赋值
var 变量名称:类型 = xxx
常量:赋值后不可改变,类似于Java中的final变量
val 常量名称:类型 = xxx
4.2、关键字
4.3、注释
object HelloWorld {
/* 这是一个 Scala 程序
* 多行注释
*/
def main(args: Array[String]) {
// 单行注释
// 输出 Hello World
println("Hello, world!")
}
}
4.4、换行
Scala是面向行的语言,语句可以用分号(;)结束或换行符。如果一行只有一个语句,则分号可有可无;如果一行里写多个语句,则需要分号
val s = "换行"; println(s)
4.5、package
Scala 使用 package 关键字定义包,在Scala将代码定义到某个包中有两种方式:
第一种方法和 Java 一样,在文件的头定义包名,这种方法就后续所有代码都放在该包中
package scalatest
class HelloWorld
第二种方法,可以在一个文件中定义多个包
package scalatest {
class HelloWorld
}
4.6、引用包
Scala 使用 import 关键字引用包
import java.awt.Color // 引入Color
import java.awt._ // 引入包内所有成员
def handler(evt: event.ActionEvent) {
// java.awt.event.ActionEvent
... // 因为引入了java.awt,所以可以省去前面的部分
}
import语句可以出现在任何地方,而不是只能在文件顶部。import的效果从开始延伸到语句块的结束。这可以大幅减少名称冲突的可能性。
如果想要引入包中的几个成员,可以使用selector(选取器)
import java.awt.{
Color, Font}
// 重命名成员
import java.util.{
HashMap => JavaHashMap}
// 隐藏成员
import java.util.{
HashMap => _, _} // 引入了util包的所有成员,但是HashMap被隐藏了
4.7、字符串插值
- s字符串插值,用$可以引用变量和表达式
object Test {
def main(args: Array[String]): Unit = {
var name = "Kyrie Irving"
println(s"my name is $name")
println(s"1+1=${1+1}")
}
}
结果
- f字符串插值,用于格式化输出
object Test {
def main(args: Array[String]): Unit = {
val name = "Kyrie"
val score = 57d
println(f"$name%s got $score%.1f points")
}
}
结果
- raw插值,屏蔽转义符等控制效果
object Test {
def main(args: Array[String]): Unit = {
println(s"a\nb")
println("----------")
println(raw"a\nb")
}
}
结果
4.8、条件控制
- if和if…else…
val x = 10
if(x==10)println("x等于10")
println("------------")
if(x>10){
println("x大于10")
}else{
println("x小于等于10")
}
4.9、循环控制
- while循环
object Test {
def main(args: Array[String]): Unit = {
var a = 10
while(a>=8){
println(a)
a = a-1
}
}
}
- do…while循环
object Test {
def main(args: Array[String]): Unit = {
var a = 10
do{
println(a)
a = a + 1
}while(a<=13)
}
}
- for循环
循环条件to和until都表示区间,to前包且后包,until前包后不包
object Test {
def main(args: Array[String]): Unit = {
for(a <- 1 to 3){
print(a+"\t")
}
for(a <- 1 until 3){
print(a+"\t")
}
}
}
- for多重循环——九九乘法表
def main(args: Array[String]): Unit = {
for(i <- 1 to 9;j <- 1 to i){
print(s"$j*$i=${i*j}\t")
if(i==j)println()
}
}
- for循环过滤
def main(args: Array[String]): Unit = {
for(i <- 1 to 10;if i%2==0;if i<9){
print(i+"\t")
}
}
- 循环中断
Scala 语言中默认是没有 break 语句,需要导包
import scala.util.control.Breaks._
源码如下
case
import scala.util.control.Breaks._
for(elem <- 1 to 4){
print(6)
if(elem%3==0){
break()
}
}
- 循环返回值
for循环中的yield 会把当前的元素记下来保存在集合中,循环结束后将返回该集合。也称for推导式
def main(args: Array[String]): Unit = {
var ret = for(i <- 1 to 10;if i%2==0;if i<9) yield i;
for(j <- ret){
print(j+"\t")
}
}
4.10、块表达式
(1)块表达式也是一个结果,{}中的最后一行的结构就是块表达式的结果
(2)如果最后一行是赋值语句,则为unit()
def main(args: Array[String]): Unit = {
val myblock = {
var x = 2
var y = 3
x+y
}
println(myblock)
}
val myblock = {
var x = 2
var y = 3
x = x+y
}
println(myblock)
五、数组、元组、集合
5.1、数组
- 存储固定大小的元素
- 数组索引从0开始
- 泛型使用方括号 [ ]
- 数组访问使用圆括号 ( )
5.2、元组
- 可以包含不同类型的元素
- 最多支持22个元素(Tuple1~Tuple22)
- 除了Tuple1外,其他可以用()直接创建
- 使用下划线 “_” 访问元素,"_1"表示第一个元素
5.3、集合
1、分类
- Seq:序列,元素按顺序排列 (List)
- Set:集合,元素不重复
- Map:映射,键值对集合
所有的集合都继承自Traversable,都可以使用它里面的函数
2、可变/不可变
-
不可变集合
scala.collection.immutable
,默认scala中选择不可变集合
-
可变集合
scala.collection.mutable
,可以修改、添加或移除一个集合的元素