Kotlin编程实战-第三部分 Link to heading
第三部分 函数式Kotlin Link to heading
第10章 使用lambda进行函数式编程 Link to heading
10.2 lambda表达式 Link to heading
lambda表达式是没有名称的函数,其返回类型是推断的。
通常一个函数有四个部分:名称、返回类型、参数列表和主体。
lambda只保留函数最重要的部分——参数列表和主体。
{ parameter list -> body }
lambda被包裹在{}中。使用连字符箭头(->)把主体与参数列表分开,主体通常是单个语句或表达式,但也可以是多行。但是尽量只使用单行语句。
fun isPrime(n: Int) = n>1 && (2 until n).none{ n % it == 0}
如果传递给函数的lambda只接受一个参数,那么我们可以省略参数声明,而使用一个特殊的隐式名称it。
接受lambda
现在让我们看看如何创建一个接收lambda的函数。
fun walkTo(action: (Int)->Unit, n: Int) = (1..n).forEach{ action(it) }
在Kotlin中,对于参数,我们先指定变量名,然后是类型,比如n: Int。这种格式也用于lambda参数。
把lambda作为最后一个参数传递
修改一下上面这个代码参数的顺序
fun walkTo(n: Int, action: (Int)->Unit) = (1..n).forEach{ action(it) }
walkTo(5){print(it)}
使用函数引用
({x -> someMethod(x)})
// 可以替换为
(::SomeMethod)
// 如果传递到另一个lambda中,可以省略::
(someLambda)
fun walkTo(n: Int,action: (Int)->Unit) = (1..n).forEach{action(it)}
fun walkTo(n: Int,action: (Int)->Unit) = (1..n).forEach(action)
walkTo(5){System.out.print(it)}
walkTo(5,System.out::print)
10.6 带有lambda的内联函数 Link to heading
你可以使用inline关键字来提高接收lambda的函数的性能。
如果一个函数标记为inline,那么该函数的字节码将在调用位置置为内联,而不是调用该函数。
inline fun invokeTwo(
n: Int,
action1: (Int) -> Unit,
action2: (Int) -> Unit,
): (Int) -> Unit{
}
同时可以对参数进行指定不要inline
inline fun invokeTwo(
n: Int,
action1: (Int) -> Unit,
noinline action2: (Int) -> Unit,
): (Int) -> Unit{
}
第11章 内部迭代和延迟计算 Link to heading
11.1 内部迭代 Link to heading
内部迭代涉及许多专用的工具,如filter()、map()、flatMap()、reduce()等等。
filter()返回的集合的大小从0到n不等,其中n是原始集合中的元素数。结果是一个子集合也就是说,输出集合中的值是原始集合中的值。
map()返回集合的大小与原始集合的大小相同。传递给map()的lambda应用于原始集合中的每个元素,结果是这些转换后的值的集合。
reduce()的lambda接受两个参数。第一个参数是一个累计值,第二个参数是来自原始集合的一个元素。lambda的结果是新的累计值。reduce()的结果是最后一次调用lambda的结果。
11.3延迟计算序列 Link to heading
简单地说,集合是急切的,而序列是懒惰的。
我们可以使用asSequence()方法将一个集合包装成一个序列,然后应用我们在集合上使用的相同的内部迭代器方法,但这次是在序列上使用。
val nameOfFirstAudlut = people.asSquence()
.filter(::isAdult)
.map(::fetchFirstName)
.first()