[Scala03]求值策略、函数、柯里化

1、求值策略(evaluation strategy)

在scala中,所有的运算都是基于表达式的,我们要对运算进行求值,会有不一样的方法和策略。

在scala有两种不同的求值策略,一种叫call by value(严格求值),一种叫call by name(非严格求值)。

1)call by value:对函数实参进行求值,且仅求值一次

2)call by name:函数实参每次都函数体内被用到都会求值

3)scala通常使用call by value,如果函数形参类型使用=>开头,则会使用call by name

[Scala03]求值策略、函数、柯里化

call by name 和call by value在不同场景下性能优劣不同,以上例子左边call by valuex性能更高,右边call by name性能更高

[Scala03]求值策略、函数、柯里化

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

2、scala函数与匿名函数

1)函数可以作为参数传递给另一个函数、函数可以作为返回值、函数可以赋给变量、函数可以存储在数据结构中

2)函数类型:

函数类型格式为A=>B,表示这个函数接受的参数类型为A,经过一系列的函数变换,返回值为类型B

例子:Int=>String 把整型映射为字符串类型的函数类型

3)高阶函数:用函数作为形参或返回值的函数,我们称之为高阶函数

scala> def operate(f:(Int,Int) =>Int):Int=f(3,5)
operate: (f: (Int, Int) => Int)Int
scala> operate((x,y) => x+y)
res4: Int = 8

#operate函数接受的参数为函数f,函数f的函数类型为(Int,Int) =>Int

#函数形参为函数时,传参格式传参格式参照上式

4)匿名函数(anonymous function)

匿名函数就是函数常量,也叫函数文字量

格式:

(形参列表)=>{函数体}

举例:

scala> (x: Int) => x*x
res5: Int => Int = <function1>
scala> (x: Int,y: Int) => x+y
res6: (Int, Int) => Int = <function2>

scala> var add=(x:Int,y:Int)=>x+y
add: (Int, Int) => Int = <function2>

scala> add(1,2)
res7: Int = 3

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

#将匿名函数赋给另一个函数后,调用该函数时的正确方式用红色字体注明

3、柯里化(curried function)

柯里化函数把具有多个参数的函数转换为一条函数链,每个节点上都是单一函数

将def add(x:Int,y:Int)=x+y化成def add(x:Int)(y:Int)=x+y叫柯里化函数,这两个函数等价

4、递归函数(recursive function)

递归函数是函数式编程中一门非常重要的技术

scala> def factorial(n:Int):Int={if(n<=0)1 else n*factorial(n-1)}
factorial: (n: Int)Int
scala> factorial(3)
res9: Int = 6

#以上的递归容易造成堆栈溢出,所以我们尾递归函数对递归进行优化

尾递归函数:

尾递归函数中所有递归形式的调用都出现在函数的末尾,当编译器检测当当前递归函数的调用是尾递归时,它会覆盖当前的活动记录而不是在栈中创建一个新的

scala> @annotation.tailrec
     | def factorial(x:Int,y:Int):Int={
     | if(x<=0)y
     | else factorial(x-1,x*y)}
factorial: (x: Int, y: Int)Int
scala> factorial(3,1)
res11: Int = 6

5、综合性例子

[Scala03]求值策略、函数、柯里化

[Scala03]求值策略、函数、柯里化