目录
函数式编程的特点
函数式编程本质是函数的集合,比如想要过滤一个集合中的奇数:
fun testFunX(): Unit {
val list = listOf(1,2,3,4,5,6,7)
val lx = list.filter { it %2 == 1 } // filter函数,参数是lambda表达式
println(list)
println(lx)
}
函数式编程是关于不变性的编程范式;
函数式编程是关于函数集合的编程范式;
函数式编程的特点:
- 函数也是一种数据类型,可以作为参数,同时函数的返回值也可以是函数 —— 函数既可以作参数,也可以作返回值,即一等函数支持。
- 纯函数,不改变外部的数据结构,是没有副作用的函数。不去修改数据,会创建一份新的数据映射,会使用不可变的数据。
- 函数的组合(compose function):
- 函数式编程通过不同函数的组合来构建程序的逻辑。
- 面向对象编程是通过对象之间发送消息来构建程序的逻辑。
声明函数
- 声明函数
// 使用 fun 关键字来声明函数
fun sum1(x: Int, y: Int): Int {
return x + y
}
- 声明函数类型的变量
函数也可以当作变量来使用,声明一个函数类型的变量sum2
:
val sum2 = fun (x: Int, y: Int):Int {return x + y}
fun testSum2(): Unit {
println(sum2) // 输出: (kotlin.Int, kotlin.Int) -> kotlin.Int
println(sum2(3,9)) // 输出: 12
}
(kotlin.Int, kotlin.Int) -> kotlin.Int
—— 这个带“->”的表达式就是一个函数类型
,
表示一个 输入两个Int类型值、输出一个Int类型值 的函数。
- 其它形式 声明函数
// 使用表达式声明sumX()函数
fun sumX(x: Int, y: Int) = x+y
// 使用fun关键字声明了一个匿名函数,同时直接使用表达式来实现函数
// { x+y } 的类型是 () -> kotlin.Int 函数;{ x+y }表达式返回的是一个Lambda表达式
val sumF = fun(x: Int, y: Int) = { x+y }
// 使用表达式声明 sumF2()函数,{}表示一个Lambda表达式
fun sumF2(x: Int, y: Int) = { x + y }
Lambda表达式
fun testFunX(): Unit {
val list = listOf(1,2,3,4,5,6,7)
val lx = list.filter { it %2 == 1 } // filter()函数,参数是lambda表达式
println(list)
println(lx)
}
filter()函数的参数 { it %2 == 1 } 是lambda表达式,
filter()函数的参数只有一个,因此括号省略了。
filter()函数的完整写法:
list.filter({ it %2 == 1 })
// 或
list.filter({ it -> it %2 == 1 })
filter()函数的声明:
public inline fun <T> Iterable<T>.filter(predicate: (T) -> Boolean): List<T> {
return filterTo(ArrayList<T>(), predicate)
}
public inline fun <T, C : MutableCollection<in T>> Iterable<T>.filterTo(destination: C, predicate: (T) -> Boolean): C {
for (element in this) if (predicate(element)) destination.add(element)
return destination
}
filter()函数的参数是 一个函数 predicate: (T) -> Boolean
.
testFunX()函数完整写法:
val isOdd = {it: Int -> it %2 ==1} // lambda表达式
fun testFunY(): Unit {
val list = listOf(1,2,3,4,5,6,7)
val lx = list.filter(isOdd) // lambda表达式作为参数
println(list)
println(lx) // 输出:[1, 3, 5, 7]
println(isOdd) // 输出:(kotlin.Int) -> kotlin.Boolean
}
高阶函数
Kotlin高阶函数:以另一个函数为参数或者返回值的函数。
高阶函数是多个函数的复合。
知识点:类型别名
typealias
。
案例:输入一个字符串列表,过滤出字符串元素长度为奇数的列表并输出。
1 . 可以将这个需求拆解成两个函数来解决:
val len = fun (s: String?) = s?.length ?:0 // 计算字符串的长度
val odd = fun (i:Int) = i%2 == 1 // 判断输入值是否是奇数
2 . 再使用函数 so 来封装"字符串的长度是否是奇数"的逻辑
// 封装"字符串的长度是否是奇数"
val so = fun (len: (String?)->Int, odd:(Int)->Boolean) : (String?)->Boolean = {odd(len(it))}
3 . 这个函数的声明比较长,可以简化一下:
// 使用类型别名来简化函数类型:
typealias L = (String?)->Int
typealias O = (Int)->Boolean
typealias S = (String?)->Boolean
3 .1. 简化后的so函数
// 简化 so 函数的写法:
val sop = fun (len: L, odd: O) : S = {odd(len(it))}
// {odd(len(it))} 是 lambda表达式,返回的是一个 (String?)->Boolean函数类型
4 . 测试
fun testSLO(): Unit {
val strList = listOf("x","xy","xyz","xyz1","xyz12","xyz123","xyz1234")
println(strList)
println(strList.filter(so(len,odd))) // 输出:[x, xyz, xyz12, xyz1234]
println(strList.filter(sop(len,odd))) // 输出:[x, xyz, xyz12, xyz1234]
println(strList)
}
so(len,odd) 以及 sop(len,odd) 这样的复合函数代码 和 数学公式很接近,简单易懂。