函数式编程思想:将函数传来传去
1、将函数A作为函数B的参数进行传递
2、将函数A作为函数B的返回值类型
需要明确的是函数的类型 -- 主要是由参数列表和返回值类型决定的
使用scala语法描述一个函数类型:
举例:String => Int
一、函数作为参数进行传递
object FunDemo4 {
def main(args: Array[String]): Unit = {
//strToInt是一个参数为String,返回值为Int类型的函数
def strToInt(str: String): Int = str.toInt
// println(strToInt("100"))
//函数也可看作为一个对象
val strToIntTemp: String => Int = strToInt
// println(strToIntTemp("200"))
/**
* 函数作为参数进行传递
* 作用:本质上就是将函数的主题逻辑抽取出来,当作参数传递给函数
*/
def fun(s: String, stoi: String => Int): Unit = {
val res: Int = stoi(s)
println(res + 200)
}
def strToInt1(str: String): Int = str.toInt + 100
/**
* fun()函数的函数参数,可以是不同的实现,只要传入的函数参数符合参数是String返回值为Int类型即可
*/
fun("100", strToInt) //300
fun("100", strToInt1) //400
/**
* 函数作为方法参数传递的时候,这里的参数可以使用lambda表达式改写
* lambda表达式 -->匿名函数(没有名字的函数)
* (s:String)=>s.toInt
*/
//匿名函数
val f1: String => Int = (s: String) => s.toInt
println(f1("1"))
//函数只有一行的时候,传参可以直接传入一个匿名函数
fun("300", (s:String)=>s.toInt+100) //600
//lambda表达式的类型可以自动推断,可以省略
fun("300",s=>s.toInt+100)
//如果传入的函数参数有且仅用了一次,可以使用_替代
fun("300",_.toInt+100)
}
}
二、函数作为函数的参数传递的应用
/**
* 函数作为函数的参数传递的应用
*/
object FunDemo5 {
def main(args: Array[String]): Unit = {
//创建一个数组
val arr: Array[Int] = Array[Int](1, 11, 33, 22, 44, 77, 55, 66)
//定义一个函数,参数为Int类型,无返回值(Unit)
def fun1(i: Int) = println(i)
//foreach函数的作用是将数组中的每一个元素取出来当做参数传递给后面的函数
arr.foreach(fun1)
println("="*100)
//使用匿名函数的方式传递参数
arr.foreach((s:Int)=>println(s))
println("="*100)
//简写1:参数的类型可以做自动类型推断
arr.foreach(s=>println(s))
println("="*100)
//简写2:如果函数体中的参数只使用了一次,可以使用_代替
arr.foreach(println(_))
println("="*100)
/**
* 观察println的源码:
* Any-->等同于java中的object
*/
//面向函数编程也可以使用多态
arr.foreach(println)
}
}
三、函数作为返回值返回、柯里化、偏函数
/**
* 2、函数作为返回值返回
*/
object FunDemo6 {
def main(args: Array[String]): Unit = {
/**
* fun函数:
* 参数:是一个参数列表为String返回值为Int类型的函数
* 返回值:是一个参数列表为String类型返回值为Int类型的函数
*/
def fun(s: String => Int): String => Int = {
println("好好学习,天天向上")
s
}
//不额外定义函数传参
val stringToInt: String => Int = fun(s => s.toInt)
def fun1(str: String): String => Int = {
//因为fun1函数调用完毕后需要返回一个参数类型是String,返回值为Int类型的函数
//所以需要再fun1函数内部创建一个函数进行返回
def show(s: String): Int = str.toInt + s.toInt
show
}
//调用fun1函数
val fun2: String => Int = fun1("100")
println(fun2("100")) //fun2就是fun1返回的show函数
//fun1函数调用的简化写法
val i: Int = fun1("100")("100")
println(i)
/**
* 当函数原本一次性传递多个参数的时候,现在改成分开传参的形式。增加了函数的灵活性和可复用性
* 这样调用的方式有一个数学概念:柯里化
* Scala函数的柯里化:函数的返回值依旧是一个函数,可以继续传参
*/
def fun5(str1:String,str2:String): Int = {
str1.toInt+str2.toInt
}
//中间由scala产生的函数,称之为偏函数
val show2: String => Int = fun5("100", _)
println(show2("100"))
}
}