Scala语言初始01
简介
创始人:Martin Odersky马丁·奥德斯基
Scala是一门以jvm为运行环境的静态类型变成语言,具备面向对象及函数式编程的特性
六大特性
Java 和 scala 可以混编
2. 类型推测(自动推测类型)
3. 并发和分布式( Actor )
4. 特质,特征(类似 java 中 interfaces 和 abstract 结合)
5. 模式匹配(类似 java 中的 switch...case )
6. 高阶函数
Scala应用场景
kafka:分布式消息队列,内部代码经常用来处理并发问题,用Scala可以大大简化其代码
spark:方便处理多线程场景,另外spark主要用作内存计算,经常要用来实现复杂的算法。利用Scala这种函数式编程语言可以大大简化代码
Scala基础
标识符
首先就是要区分大小写,Scala和Java一样对于大小写敏感
类名:与Java一样,首字母要大写,如果是几个单词构成的,则每个单词第一个字母都要大写
方法名:所有的方法名称第一个字母要小写,如果是若干个单词构成的名称,则每个单词首字母大写
程序文件名:程序文件的名称应该与对象名称完全匹配,保存文件的时候,应该保存它使用的对象名称。且后缀为.Scala
数据类型

any图示

比较特殊的None是Option的两个子类之一,另一个是Some,用于安全的函数返回值
Scala推荐才可能返回空的方法中使用Option[x]作为返回的类型,如果有值就返回Some[x],否则就返回None
def get(key: A): Option[B] = {
if (contains(key))
Some(getValue(key))
else
None
}
变量和常量
注意如下两点:
定义变量或者常量的时候,也可以写上返回的类型,一般省略,如: val a:Int = 10
var VariableName : DataType [= Initial Value]
val VariableName : DataType [= Initial Value]
变量:在程序运行过程中其值可能发生改变的量叫做变量。
常量:在程序运行过程中其值不会发生变化的量叫做常量。
在 Scala 中声明变量和常量不一定要指明数据类型,在没有指明数据类型的情况下,其数据类型是通过变量或常量的初始值推断出来的。
如果在没有指明数据类型的情况下声明变量或常量必须要给出其初始值,否则将会报错。
变量:用var定义,且可更改 常量:用val定义,且不可更改
var name = "zhangsan"
println(name)
name ="lisi"
println(name)
val gender = "m"
//gender = "w" //错误,不能给常量再赋值
运算符
一个运算符是一个符号,用于告诉编辑器来执行指定的数学运算和逻辑运算
Scala包含丰富的内置运算符
+ - * / %
关系运算符

逻辑运算符

位运算符

赋值运算符

逻辑语句
Scala if...else语句是通过一条或者多条语句的执行结果(true和false)来决定执行的代码块。和Java一样的语法结构,单双多分支这三种顺序控制结构
/**
* StdIn键盘标准输入 scala.io包下的
*/
def main(args: Array[String]): Unit = {
println("请输入年龄:")
val age = StdIn.readInt()
if(age >= 18 && age < 100){
println("成年")
}else if( age > 0 && age < 18){
println("未成年")
}else{
println("???")}}
循环语句
循环语句允许我们多次执行同一个语句或是语句组
区间的获取
to和until 1 to 10,返回1-10闭区间,1 until 10返回1-10,开区间
普通的for循环
/** Range 可以是一个数字区间表示 i to j ,或者 i until j。左箭头 <- 用于为变量 x
赋值。*/
for( var x <- Range ){
statement(s);}
多层for循环
//可以分号隔开,写入多个list赋值的变量,构成多层for循环
//scala中 不能写count++ count-- 只能写count+
var count = 0;
for(i <- 1 to 10; j <- 1 until 10){
println("i="+ i +", j="+j)
count += 1}
println(count);
//例子: 打印小九九
for(i <- 1 until 10 ;j <- 1 until 10){
if(i>=j){
print(i +" * " + j + " = "+ i*j+" ")
}
if(i==j ){
println()}}
判断for循环
//可以在for循环中加入条件判断
for(i<- 1 to 10 ;if (i%2) == 0 ;if (i == 4) ){
println(i)}
for循环与yield
yield 关键字返回一个集合(`for {子句} yield {变量或表达式}`,原来的集合不会被改变,只会通过你的for/yield构建出一个新的集合。)
将 for 循环的返回值作为一个变量存储
var retVal = for{ var x <- List
if condition1; if condition2...
}yield x
object Test {
def main(args: Array[String]) {
var a = 0;
val numList = List(1,2,3,4,5,6,7,8,9,10);
// for 循环
var retVal = for{ a <- numList
if a != 3; if a < 8
}yield a
// 输出返回值
for( a <- retVal){
println( "Value of a: " + a );}}}
while循环(两种方式),while(){}与do{} while()
//将for中的符合条件的元素通过yield关键字返回成一个集合
val list = for(i <- 1 to 10 ; if(i > 5 )) yield i
for( w <- list ){
println(w)
}
// while 循环
var index = 0
while(index < 100 ){
println("第"+index+"次while 循环")
index += 1
}
index = 0
do{
index +=1
println("第"+index+"次do while 循环")
}while(index <100 )
方法与函数
Scala 使用 def 关键字告诉编译器这是一个方法。
返回值类型与返回值
在参数后面加一个冒号和类型来显式地指定返回类型。
方法可以写返回值的类型也可以不写,会自动推断,但是如果有显式的Return有时候不能省略,必须写
Scala 中函数有返回值时,可以写 return ,也可以不写 return ,不写 return 时会把函数中最后一行当做结果返回。
如果去掉方法体前面的等号,那么这个方法返回类型必定是 Unit 的。scala可以把任意类型转换为 Unit 。
假设,函数里面的逻辑最后返回了一个 string ,那么这个返回值会被转换成 Unit ,原本逻辑的值会被丢弃
如果返回值可以一行搞定,可以将{}省略不写
scala规定方法的传过来的参数为val的,不是var的
函数的定义
Scala的函数是基于Function家族,0-22,一共23个Function Trait可以被使用,数字代表了Funtcion的入参个数

Java里只有方法都能适应一切需求,那scala又提出函数的概念肯定有意义。
函数可以直接赋值给变量,可以让函数很方便的传递
闭包(closure),可以把灵活操作代码块,从而引申出其他灵活的语法
var f1 = (s: String) => {
println("hi1 " + s);
}
var f2 = (s: String) => {
println("hi2 " + s);
}
方法与函数
在接触java的时候,有时候用函数来称呼某个method(实在找不出词了),有时候用方法来称呼
某个method,虽然method的中文翻译就是“方法”,但对于java来说,方法和函数是等价的,或者
说没有函数这个概念。而对于scala,这两者似乎有一个较为明确的边界
Scala 有方法与函数,二者在语义上的区别很小
Scala 方法是类的一部分,而函数是一个对象 对象的引用可以赋值给一个变量。换句话来说在类中定义的函数即是方法。
Scala 中的方法跟 Java 的类似,方法是组成类的一部分。
Scala 中的函数则是一个完整的对象,Scala 中的函数其实就是继承了 Trait 的类的对象。
Scala 中使用 val 语句可以定义函数,def 语句定义方法。
def m(x: Int) = x + 3
val f = (x: Int) => x + 3
方法与函数的区别
当函数定义在类中,就表示方法,其他的都称为函数
函数可以作为一个参数传入到方法中,而方法就不行
在Scala中无法直接操作方法,如果要操作方法,必须先将其转换成函数,
通常情况下,编译器会自动将方法转换成函数
val f = m _ //表示将m 方法转换为函数
在需要函数的地方,如果传递一个方法,会自动进行ETA展开(把方法转换为函数)
def main(args: Array[String]): Unit = {
method02(method01, "libai")
}
def method01(s: String) = {
println("hi4 " + s);
}
def method02(fun: String => Unit, str: String) = {
fun(str);
}