Scala基本语法

函数式编程

副作用

var x = 1

def xplusY_v1(y:Int) = x + y  无副作用

def xplusY_v2(y:Int) = {x += y;x} 有副作用,对x产生影响

引用透明

对于相同的输入,总是得到相同的输出

如果f(x)的参数x和函数体都是引用透明的,那么函数f是纯函数

append函数违反了引用透明

不变性

为了获得引用透明性,任何值都不能变化

val:immutable variable      -----------   常量

var:mutable variable     --------------  变量

lazy val:定义惰性求值常量。(应用场景:该变量有可能不会被用到,当该变量第一次使用,才会被求解)

可以不显示指定变量的类型,因为Scala会自动进行类型推导

scala>lazy val f = 20 * 30

f:Int = <lazy>

Unit 相当于java中的void,无返回值

scala>def foo() = throw new Exception("error occurred")

foo:()Nothing

scala>val name = "ChenFang"

name:String = ChenFang

scala>s"my name is ${name}"

res0:String = my name is ChenFang

代码块

{exp1;exp2}

{

exp1

exp2

}

函数

def functionName(param1:param1Type,param2:param2Type):ReturnType = {

//function body:expressions

}

object func_example{

def hello(name:String):String = {

s"Hello,${name}"

}

hello("ChenFang")

def add(x:Int,y:Int) = x + y

}
if表达式

if(logical_exp) valA else valB

if(true) 1 else 2    //>res0:Int = 1

if(false) 3 else 4    //>res1:Int = 4

val a = 1          //>a:Int = 1

if(a==1) a        //>res2:AnyVal = 1

if(a!=1) "not one"   //>res3:Any=()

if(a!=1) "not one" else a   //>res4:Any = 1

object worksheet_chenfang{

val l = List("alice","bob","cathy")

for(

s<-l  //遍历List集合

)println(s)

for{

s<-l

if(s.length>3) //filter

}println(s)

val result_for = for{

s<-l

s1 = s.toUpperCase()//variable binding

if(s1!="")

}yield(s1) //generate new collection

//result_for:List[String] = List(ALICE,BOB,CATHY)

}
try表达式

try{

Integer.parseInt("dog")

}catch{

case_=>0   //下划线是通配符

}finally{

println("always be printed")

}
match 表达式

exp match{//主要用在pattern match中
    case p1 => val1
    case p2 => val2
    ...
    case _ => valn
} 

code match{
    case 1 => "one"
    case 2 => "two"
    case _ => "others"
}
"_"通配所有对象,相当于java里的default

求值策略
Scala里有两种求值策略(Evaluation Strategy)
Call By Value - 对函数实参(参数表达式)求值,且仅求值一次
Call By Name - 函数实参每次在函数体内被用到时都会求值


Scala通常使用Call By Value 
如果函数形参类型以 => 开头,那么会使用Call By Name

def foo(x:Int) = x  //call by value
def foo(x:=>Int) = x //call by name


scala>def bar(x:Int,y:=>Int) = 1
bar:(x:Int,y:=>Int)Int

scala>def loop():Int = loop
loop:()Int

scala>bar(1,loop)
res0:Int = 1

scala>bar(loop,1)
//因为需要先计算出loop,才能继续下一步。由于loop是死循环,所以该函数进入死循环
Scala语言支持
1、把函数作为实参传递给另一个函数
2、把函数作为返回值
3、把函数赋值给变量
4、把函数存储在数据结构里
在Scala中,函数就像普通变量一样,可以应用到不同的地方,同样也具有函数的类型


在Scala中,函数类型的格式为A=>B,表示一个接受类型A的参数,并返回类型B的函数
例子:Int=>String是把整型映射为字符串的函数类型


高阶函数
用函数作为形参或返回值的函数,称为高阶函数
def operate(f:(Int,Int)=>Int)={
    f(4,4)
}

def grreting() = (name:String)=>{"hello"+" "+name}
匿名函数
匿名函数(Anonymous Function),就是函数常量,也称为函数文字量(Function Literal)
在Scala里,匿名函数的定义格式为
   (形参列表)=>{函数体}

例子1: (x: Int) => x*x

例子2: (x: Int,y: Int) => x+y

例子3:

var add = (x: Int,y: Int)=> x+y //add是一个具有函数类型的变量

add(1,2) //返回值:Int=3

def greeting() = (name:String) => {s"Hello $name"}

greeting()("World")

def greeting(age: Int) = (name:String) => {s"Hello $name,your age is $age"}

greeting(23)("Flygar")
Scala柯里化(Curried Function)
把具有多个参数的函数转换为一条函数链,每个节点上是单一参数
例如:以下两个add函数定义是等价的

def add(x:Int,y:Int) = x + y
def add(x:Int)(y:Int) = x + y //Scala里柯里化的语法

例子:
def curriedAdd(a:Int)(b:Int) = a + b
curriedAdd(2)(2)  //4
val addOne = curriedAdd(1)_   //Int=>Int
addOne(2)  //3
在函数式编程中,可以运用柯里化特性来构造新的函数,而不需要重新定义新函数。


递归函数
递归函数在函数式编程中是实现循环的一种技术

例子:计算n!

def factorial(n:Int):Int = 
    if(n<=0) 1
    else n*factorial(n-1)
尾递归函数
    尾递归函数中所有的递归形式的调用都出现在函数的末尾。
    当编译器检测到一个函数调用是尾递归的时候,它就覆盖当前的活动记录而不是在栈中去创建一个新的。
@annotation.tailrec
def factorial(n:Int,m:Int):Int = 
    if(n<=0) m
    else factorial(n-1,m*n)

factorial(5,1)  
图截自慕课网视频:https://www.imooc.com/video/11275


scala.collection.immutable
集合有三大类:Set、Map、Seq

scala>val a = List(1,2,3,4)
a:List[Int] = List(1,2,3,4)

scala>val b = 0::a
b:List[Int] = List(0,1,2,3,4)

scala>val c = "x"::"y"::"z"::Nil   //从后面开始连接
c:List[String] = List(x,y,z)

scala>"z"::Nil  //Nil为空
res0:List[String] = List(z)

scala>"y"::res0
res1:List[String] = List(y,z)

scala>"x"::res1
res2:List[String] = List(x,y,z)


scala>val d = a:::c  //连接两个集合
d:List[Any] = List(1,2,3,4,x,y,z)

访问集合内元素

scala>a.head
res3:Int = 1

scala>d.head
res4:Any = 1

scala>c.head
res5:String = x

scala>a.tail  //返回除了第一个元素之外的元素列表
res6:List[Int] = List(2,3,4)

scala>c.tail
res7:List[String] = List(y,z)

scala>a.isEmpty
res8:Boolean = false

scala>Nil.isEmpty
res9:Boolean = true

scala>def walkthru(l:List[Int]):String = {
    if(l.isEmpty) ""
    else l.head.toString + " " + walkthru(l.tail)
    }
walkthru:(l:List[Int])String

scala>walkthru(a)
res10:String = "1 2 3"


scala>a.filter(x => x%2==1) //filter会遍历列表,然后通过匿名函数筛选 
res11:List[Int] = List(1,3)

scala>"99 Red Balloons".toList
res12:List[Char] = List(9,9, ,R,e,d, ,B,a,l,l,o,o,n,s)

scala>"99 Red Balloons".toList.filter(x => Character.isDigit(x))
res13:List[Char] = List(9,9)

scala>"99 Red Balloons".toList.takeWhile(x => x!='B')
res14:List[Char] = List(9,9, ,R,e,d, )

scala>c.map(x => x.toUpperCase)
res15:List[String] = List(X,Y,Z)

scala>c.map(_.toUpperCase)
res16:List[String] = List(X,Y,Z)

scala>a.filter(_%2 == 1)
res17:List[Int] = List(1,3)

scala>a.filter(_%2 == 1).map(_ + 10)
res18:List[Int] = List(11,13)

scala>val q = List(a,List(4,5,6))
q:List[List[Int]] = List(List(1,2,3),List(4,5,6))

scala>q.map(x=>x.filter(_%2==0))
res19:List[List[Int]] = List(List(2),List(4,6))

scala>q.map(_.filter(_%2==0))
res20:List[List[Int]] = List(List(2),List(4,6))

scala>q.flatMap(_.filter(_%2==0))
res22:List[Int] = List(2,4,6)

//reduceLeft(op:(T,T)=>T)
scala>a.reduceLeft((x,y)=>x+y)
res23:Int = 6

scala>a.reduceLeft( _ + _ )
res24:Int = 6

//foldLeft(Z:U)(op:(U,T)=>U)
scala>a.foldLeft(0)(_+_)
res25:Int = 6

scala>a.foldLeft(0)(_*_)
res26:Int = 6

//定义Range
scala>1 to 10 by 2
res37:scala.collection.immutable.Range = Range(1,3,5,7,9)

scala>(1 to 10).toList
res38:List[Int] = List(1,2,3,4,5,6,7,8,9,10)

scala>1 until 10
res39:scala.collection.immutable.Range = Range(1,2,3,4,5,6,7,8,9)

//Stream is a lazy List
scala>1#::2#::3#::Stream.empty
res40:scala.collection.immutable.Stream[Int] = Stream(1,?)

scala>val stream = (1 to 10000000).toStream
stream:scala.collection.immutable.Stream[Int] = Stream(1,?)

scala>stream.head
res41:Int = 1

scala>stream.tail //只对2求值
res42:scala.collection.immutable.Stream[Int] = Stream(2,?)

scala>(1,2)
res43:(Int,Int) = (1,2)

scala>1->2
res44:(Int,Int) = (1,2)

scala>(1,"Alice","Math",95.5)
res45:(Int,String,String,Double) = (1,Alice,Math,95.5)

scala>val t=(1,"Alice","Math",95.5)
t:(Int,String,String,Double) = (1,Alice,Math,95.5)

scala>t._1
res46:Int = 1

scala>t._2
res47:String = Alice

scala>def sumSq(in:List[Int]):(Int,Int,Int)=
    | in.foldLeft((0,0,0))((t,v)=>(t._1+1,t._2 + v,t._3 + v*v))
sumSq:(in:List[Int])(Int,Int,Int)

scala>sumSq(a)
res50:(Int,Int,Int) = (3,6,14)

scala>val p = Map(1 -> "David",9 -> "Elwood")
p:scala.collection.immutable.Map[Int,String] = Map(1 -> David,9 -> Elwood)

scala>p(1)
res51:String = David

scala>p(9)
res52:String = Elwood

scala>p.contains(1)
res53:Boolean = true

scala>p.contains(2)
res54:Boolean = false

scala>p.keys
res55:Iterable[Int] = Set(1,9)

scala>p.values
res56:Iterable[String] = MapLike(David,Elwood)

scala>p + (8 -> "Archer")
res57:scala.collection.immutable.Map[Int,String] = Map(1 -> David,9 -> Elwood,8 -> Archer)

scala>p-1
res58:scala.collection.immutable.Map[Int,String] = Map(9 -> Elwood)


scala>p ++ List(2 -> "Alice",5 -> "Bob")//新生成一个MAP,所以下一条指令才会使得Map为空
res59:scala.collection.immutable.Map[Int,String] = Map(1->David,9->Elwood,2->Alice,5->Bob)

scala>p -- List(1,9,2)
res60:scala.collection.immutable.Map[Int,String] = Map()


scala实现快排

def qSort(a:List[Int]):List[Int] = 
    if (a.length<2) a
    else 
        qSort(a.filter( _ <a.head)) ++ 
        a.filter( _ == a.head) ++
        qSort(a.filter( _ > a.head))
scala文档:http://docs.scala-lang.org/overviews/collections/introduction.html





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值