1:求值策略
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) //y为call by name,只有被使用到时才计算
res2: Int = 1
scala> bar(loop,1) -------------x的值为call by value,则首先要拿到第一个表达式的值才可进行下面的运算
一直没有结束,loop进行死循环,没办法退出循环体
2:Scala函数与匿名函数
高阶函数:接受的参数可能是个函数,或者返回值是一个函数,或者两个皆有
例1:f为一个函数,接受两个Int类型的参数,返回值为一个Int类型的值,operate中直接调用f,
f传入(4,4),f最终会返回一个Int类型的值,f返回的值再作为operate的返回值
例子2:表示函数的返回值也是一个函数,定义一个函数greeting,函数的返回值是函数,该函数
接受一个字符串类型的参数,参数类型为name,函数的返回值为“hello”+" "+name
返回值为String => String,即匿名函数
scala> def add(x: Int, y: Int): Int = {x + y}
add: (x: Int, y: Int)Int
scala> def add2(z:Int) = { z+2 }
add2: (z: Int)Int
scala> val k = add2(add(1,2))
k: Int = 5
3:Scala柯里化
例2:实现一个函数,功能是对每个整型加1的操作,_通配后面所有的参数列表
scala> def curriedAdd(a:Int)(b:Int) = a+b
curriedAdd: (a: Int)(b: Int)Int
scala> val addOne = curriedAdd(1)_
addOne: Int => Int = <function1>
scala> addOne(2)
res2: Int = 3
4:Scala递归与尾递归
递归层数较多时可能会出现堆栈溢出,因此需要优化
只需要一个栈,m中保存的是最新的一个累乘的结果
scala> def factorial(n:Int,m:Int):Int = { if(n<=0) m else factorial(n-1,m*n)}
factorial: (n: Int, m: Int)Int
scala> factorial(5,1)
res3: Int = 120
举例:
object sumfunc {
def sum(f: Int => Int)(a: Int)(b: Int): Int = {
@annotation.tailrec
def loop(n: Int, acc: Int): Int = {
if (n > b) {
println(s"n=${n},acc=${acc}")
acc
} else {
println(s"n=${n},acc=${acc}")
loop(n + 1, acc + f(n))
}
}
loop(a,0)
} //> sum: (f: Int => Int)(a: Int)(b: Int)Int
sum(x => x)(1)(5) //> n=1,acc=0
//相当于y = x //| n=2,acc=1
//| n=3,acc=3
//| n=4,acc=6
//| n=5,acc=10
//| n=6,acc=15
//| res0: Int = 15
sum(x => x * x)(1)(5) //> n=1,acc=0
//| n=2,acc=1
//| n=3,acc=5
//| n=4,acc=14
//| n=5,acc=30
//| n=6,acc=55
//| res1: Int = 55
sum(x => x * x * x)(1)(5) //> n=1,acc=0
//| n=2,acc=1
//| n=3,acc=9
//| n=4,acc=36
//| n=5,acc=100
//| n=6,acc=225
//| res2: Int = 225
val sumSquare = sum(x => x * x)_ //> sumSquare : Int => (Int => Int) =sumfunc$$$Lambda$13/885951223@b684286
sumSquare(1)(5) //> n=1,acc=0
//柯里化 //| n=2,acc=1
//| n=3,acc=5
//| n=4,acc=14
//| n=5,acc=30
//| n=6,acc=55
//| res3: Int = 55
}