一、循环
1、for循环
1.普通循环
//to和until可以生成Range类型的集合
val list1=1 to 3 //to左闭右闭
println(list1)//Range(1, 2, 3)
val list2=1 until 3 //until左闭右开
println(list2)//Range(1, 2)
for(i <-1 to 3) print(i+" ") //1 2 3
for(i <-1 until 3) print(i+" ") //1 2
2.yield会将for每次迭代产生的值放到一个新的集合里
val x=for(i <- 1 to 3)yield
{i*i}
println(x) //Vector(1, 4, 9)
3.实现break和continue
1)break
import scala.util.control.Breaks._
breakable(
for(i <- 1 to 10){
if(i==4) break()
println(i)
}
)
1
2
3
2)continue
import scala.util.control.Breaks._
for(i <- 1 to 10){
breakable {
if (i == 4) break()
println(i)
}
}
1
2
3
5
6
7
8
9
10
二、函数
1、变参函数
object TestYuFa {
def main(args: Array[String]): Unit = {
println(add(1,2)) //3
println(add(1,2,3)) //6
}
def add(x:Int*): Int={
var sum=0;
for(i<-x){sum=sum+i}
sum
}
}
2、递归函数
求n的阶乘
def main(args: Array[String]): Unit = {
println(n_jie(3))//6
}
def n_jie(n:Int): Int={
if(n==1) return 1;
else return n*n_jie(n-1)
}
3、惰性函数
当函数被赋值给一个lazy修饰的变量时,函数在被调用时没有进行计算,直到取值时才被计算。
def main(args: Array[String]): Unit = {
lazy val x=f(10)
println("f没有被执行")
println(x) //对x取值
}
def f(n:Int): Unit={
println(n)
}
//f没有被执行
//10
//()
4、函数是第一等公民
说函数是第一等公民,是指函数和其他的数据类型处于平等的地位
1)可以将函数赋值给其他变量,即函数可赋值
2)可以将函数作为参数,传给另一个函数
3)一个函数可以作为另一个函数的返回
即出现变量的地方可以出现函数:赋值,参数,返回值
def main(args: Array[String]): Unit = {
val ju_zi2=ju_zi();println(ju_zi2)//将函数赋值给其他变量
val sum=add(add(1,2),3);println(sum) //将函数作为另一个函数的参数
println(use_da_yin) //一个函数可以作为另一个函数的返回值
}
def ju_zi():String={
"Hello World"
}
def add(a:Int,b:Int):Int={
a+b
}
def use_da_yin:String={
ju_zi()
}
//Hello World
//6
//Hello World
5、纯函数、闭包
object TestYuFa {
val a=1;
def main(args: Array[String]): Unit = {
}
//纯函数,在函数内不会用到外部的变量
def sum1(a:Int,b:Int):Int={
a+b
}
//闭包,函数内用到了函数外的变量
def sum2(b:Int):Int={
a+b
}
}
6、柯里化
def f1(a:Int,b:Int):Int={
a+b
}
def f2(a:Int)(b:Int):Int={
a+b
}
f2就是柯里化函数,即有多个参数列表的函数。
三、类
1、类和伴生对象
1)如果只存在object Person则object Person称为类对象,如果同时存在object Person和class Person则object的称为伴生对象,class称为伴生类
2)object可以看成是存储java中的静态成员,class中存非静态成员
3)object Person和class Person如果同时存在,则必须存储在相同文件中
4)object和class可以相互访问私有成员
5)在class中只能通过伴生对象名. 访问伴生对象内的内容
//同一个源文件
object Person {//伴生对象
}
class Person{//半生类
}
//一个源文件
object Person {//类对象
}
2、apply、unapply
1)apply
定义apply方法后可以用Person(name,age)代替new Person(name,age)
apply方法必须返回该类的对象
2)unapply
是apply方法的反向操作,unapply接收一个对象,然后从对象中提取值,提取的值通常是用来构造该对象的值。
object Person {
def apply(name:String,age:Int)={
new Person(name,age)
}
def unapply(p:Person):Option[(String,Int)]={
Some(p.name,p.age)
}
def main(args: Array[String]): Unit = {
val p=Person("胖胖",3) //apply
p.info//胖胖 3
val Person(n,a)=p //unapply
println(n+" "+a) //胖胖 3
}
}
class Person{
var name:String="";
var age:Int=0;
def this(name:String,age:Int)={
this()//调用系统自动生成后的主构造方法
this.name=name;
this.age=age;
}
def info:Unit= {
println(name + " " + age)
}
}
3、继承
1)class 子类名 extends 父类名{}
2)只能有一个直接父类
3)被final修饰的是不能被继承的
3)重写的函数要用overwide修饰
4、抽象类
1)含有抽象方法或抽象字段的类为抽象类。抽象类用abstract修饰
2)抽象方法:没有方法体的方法,不需要用abstract修饰
3)抽象字段:没有初始值的字段
4)创建子类对象:子类要想创建对象,必须要重写父类的抽象方法,给出方法体;必须重写父类的抽象字段,给出初始值。否则子类依旧是抽象类,无法创建对象。
5、特质
1)特质就是java中的接口,多个类具有相同的特征时,可以将这些特征独立出来,声明成一个特质
2)trait 特质名
3)如果某类存在多个特质或父类,可以用with关键字连接。一个类可以有多个特质,但只有一个直接父类。