基于JVM的编程语言Scala
Scala介绍
1、Scala官网6个特征
① Java和scala可以无缝混编
② 类型推测(自动推测类型)
③ 并发和分布式(Actor类似于多线程)
④ 特质trait,特征(类似java中interfaces 和 abstract结合)
⑤模式匹配(类似java switch)
⑥ 高阶函数(函数的参数是函数,函数的返回是函数)
注:Spark中使用的是Sacla2.10
Scala基础
1、 数据类型
数据类型 | 注释 |
Byte | 8bit的有符号数字,范围在-128 -- 127 |
Short | 16 bit有符号数字,范围在-32768 -- 32767 |
Int | 32 bit 有符号数字,范围-2147483648到2147483647 |
Long | 64 bit有符号数字,范围-9223372036854775808到9223372036854775807 |
Float | 32 bit IEEE 754单精度浮点数 |
Double | 64 bit IEEE 754双精度浮点数 |
Char | 16 bit Unicode字符范围U+0000到U+FFFF |
String | 字符串 |
Boolean | 布尔类型 |
Unit | 表示无值,和其他语言中void等同 |
Null | 空值或者空引用 |
Nothing | 所有其他类型的子类型,表示没有值 |
Any | 所有类型的超类,任何实例都属于Any类型 |
AnyRef | 所有引用类型的超类 |
AnyVal | 所有值类型的超类 |
2、变量和常量的声明
//定义变量var-->可以修改
var name ="zhangsan"
//定义常量 val-->不可修改
val sex ="m"
3、类和对象
创建类
class Person{
val name = "zhangsan"
val age = 18
def sayName() = {
"my name is "+ name
}
}
创建对象
object Lesson_Class {
def main(args: Array[String]): Unit = {
val person = new Person()
println(person.age);
println(person.sayName())
}
}
伴生类
伴生对对象
class Person(xname :String , xage :Int){
var name = Person.name
val age = xage
var gender = "m"
def this(name:String,age:Int,g:String){
this(name,age)
gender = g
}
def sayName() = {
"my name is "+ name
}
}
object Person {
val name = "zhangsanfeng"
def main(args: Array[String]): Unit = {
val person = new Person("wagnwu",10,"f")
println(person.age);
println(person.sayName())
println(person.gender)
}
}
Apply方法的使用:
object ScalaDemo01 {
def main(args: Array[String]): Unit = {
val p = new Person("zs",19)
val person = Person("wagnwu",10)
}
}
class Person(xname :String , xage :Int){
val name = "zs"
val age = xage
var gender = "m"
def this(name:String,age:Int,g:String){
this(name,age)
gender = g
}
}
object Person{
def apply(name:String,age:Int)={
new Person(name,age)
}
}
object:半生对象
object中的构造器在第一次调用执行一次,以后调用的话不会多次执行。
object会有自己的构造方法,默认是没有参数的构造方法
object放一些静态的成员或方法
半生类和半生对象放在同一个文件夹中
半生对象中有一个apply方法
class Person是object Person的半生类
object Person是class Person的半生对象
注意点:
建议类名首字母大写 ,方法首字母小写,类和方法命名建议符合驼峰命名法。
scala 中的object是单例对象,相当于java中的工具类,可以看成是定义静态的方法的类。object不可以传参数。另:Trait不可以传参数
scala中的class类默认可以传参数,默认的传参数就是默认的构造函数。
重写构造函数的时候,必须要调用默认的构造函数。
class 类属性自带getter ,setter方法。
使用object时,不用new,使用class时要new ,并且new的时候,class中除了方法不执行,其他都执行。
如果在同一个文件中,object对象和class类的名称相同,则这个对象就是这个类的伴生对象,这个类就是这个对象的伴生类。可以互相访问私有变量。
4、if else
val age =18
if (age < 18 ){
println("no allow")
}else if (18<=age&&age<=20){
println("allow with other")
}else{
println("allow self")
}
5、for,while,do…while
1、to和until 的用法
to包含两端的数
例:println(1 to 10) 打印出1-10
until左闭右开
2、创建for循环
for( i <- 1 to 10 ){
println(i)
}
3、创建双层for循环
for(i <- 1 until 10 ;j <- 1 until 10){
if(i>=j){
print(i +" * " + j + " = "+ i*j+" ")
}
if(i==j ){
println()
}
}
4、for循环中可以加条件判断,分号隔开
for(i<- 1 to 10 ;if (i%2) == 0 ;if (i == 4) ){
println(i)
}
注意:scala中不能使用count++,count—只能使用count = count+1 ,count += 1
for循环用yield 关键字返回一个集合
5、while循环,while(){},do {}while()
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 )
6、Scala函数
1、Scala函数的定义
def fun (a: Int , b: Int ) : Unit = {
println(a+b)
}
fun(1,1)
def fun1 (a : Int , b : Int)= a+b
println(fun1(1,2))
注意点:
1、 函数定义语法 用def来定义
2、 可以定义传入的参数,要指定传入参数的类型
3、 方法可以写返回值的类型也可以不写,会自动推断,有时候不能省略,必须写,比如在递归函数中或者函数的返回值是函数类型的时候。
4、 scala中函数有返回值时,可以写return,也可以不写return,会把函数中最后一行当做结果返回。当写return时,必须要写函数的返回值。
5、 如果返回值可以一行搞定,可以将{}省略不写
6、 传递给方法的参数可以在方法中使用,并且scala规定方法的传过来的参数为val的,不是var的。
7、 如果去掉方法体前面的等号,那么这个方法返回类型必定是Unit的。这种说法无论方法体里面什么逻辑都成立,scala可以把任意类型转换为Unit.假设,里面的逻辑最后返回了一个string,那么这个返回值会被转换成Unit,并且值会被丢弃。
2、递归函数
def fun2(num :Int) :Int= {
if(num ==1)
num
else
num * fun2(num-1)
}
print(fun2(5))
3、包含参数默认值的函数
def fun3(a :Int = 10,b:Int) = {
println(a+b)
}
fun3(b=2)
注意:
1.默认值的函数中,如果传入的参数个数与函数定义相同,则传入的数值会覆盖默认值
2.如果不想覆盖默认值,传入的参数个数小于定义的函数的参数,则需要指定参数名称
4、可变参数个数的函数
def fun4(elements :Int*)={
var sum = 0;
for(elem <- elements){
sum += elem
}
sum
}
println(fun4(1,2,3,4))
注意:多个参数逗号分开
5、嵌套函数
def fun5(num:Int)={
def fun6(a:Int,b:Int):Int={
if(a == 1){
b
}else{
fun6(a-1,a*b)
}
}
fun6(num,1)
}
println(fun5(5))
6、偏应用函数
偏应用函数是一种表达式,不需要提供函数需要的所有参数,只需要提供部分,或不提供所需参数。
def log(date :Date, s :String)= {
println("date is "+ date +",log is "+ s)
}
val date = new Date()
log(date ,"log1")
log(date ,"log2")
log(date ,"log3")
//想要调用log,以上变化的是第二个参数,可以用偏应用函数处理
val logWithDate = log(date,_:String)
logWithDate("log11")
logWithDate("log22")
logWithDate("log33")
7、高阶函数
函数的参数是函数,或者函数的返回类型是函数,或者函数的参数和函数的返回类型是函数的函数。
//函数的参数是函数
def hightFun(f : (Int,Int) =>Int, a:Int ) : Int = {
f(a,100)
}
def f(v1 :Int,v2: Int):Int = {
v1+v2
}
println(hightFun(f, 1))
//函数的返回是函数
//1,2,3,4相加
def hightFun2(a : Int,b:Int) : (Int,Int)=>Int = {
def f2 (v1: Int,v2:Int) :Int = {
v1+v2+a+b
}
f2
}
println(hightFun2(1,2)(3,4))
//函数的参数是函数,函数的返回是函数
def hightFun3(f : (Int ,Int) => Int) : (Int,Int) => Int = {
f
}
println(hightFun3(f)(100,200))
println(hightFun3((a,b) =>{a+b})(200,200))
//以上这句话还可以写成这样
//如果函数的参数在方法体中只使用了一次 那么可以写成_表示
println(hightFun3(_+_)(200,200))
8、柯里化函数
def fun7(a :Int,b:Int)(c:Int,d:Int) = {
a+b+c+d
}
println(fun7(1,2)(3,4))
语法部分未完,Scala语法(二)将继续进行补充。