学习kotlin第12天_lambda表达式

来源:互联网 发布:淘宝外包客服多少钱 编辑:程序博客网 时间:2024/05/19 23:18

继续昨天的,从昨天的第14个坑开始。

1、以map为例。文档上为如下代码,调用时由于lambda表达式在圆括号以外,而圆括号中已无其它参数,故可以省略

fun <T, R> List<T>.map(transform: (T) -> R): List<R> {    val result = arrayListOf<R>()    for (item in this)        result.add(transform(item))    return result}
fun main(args: Array<String>) {    var ints = arrayListOf(1, 2, 3)    val doubled = ints.map( { value -> value * 2 })    println(doubled)}

idea中该for循环提示

Loop can be replaced with stdlib operations less... (Ctrl+F1)

This inspection reports for-loops that can be replaced with a sequence of stdlib-operations (like "map", "filter" etc)

按照提示修改为

fun <T, R> List<T>.map(transform: (T) -> R): List<R> {    return this.map { transform(it) }}

发生了StackOverflowError。因为这两个map是不同的方法,this.map调用的应该是Collections.kt文件中的Iterable<T>.map方法而非当前map方法,改一下当前方法名即可。阅读源码可知该方法和源码几乎相同。

/** * Returns a list containing the results of applying the given [transform] function * to each element in the original collection. */@Suppress("NON_PUBLIC_CALL_FROM_PUBLIC_INLINE")public inline fun <T, R> Iterable<T>.map(transform: (T) -> R): List<R> {    return mapTo(ArrayList<R>(collectionSizeOrDefault(10)), transform)}

/** * Applies the given [transform] function to each element of the original collection * and appends the results to the given [destination]. */public inline fun <T, R, C : MutableCollection<in R>> Iterable<T>.mapTo(destination: C, transform: (T) -> R): C {    for (item in this)        destination.add(transform(item))    return destination}
2、如果lambda表达式的参数只有一个,则可以省略并用it代替。It在之前for循环的时候见到过,当时不知道it是什么,以为直接是这个集合的item呢,确实也是,但它大多是该方法通过for(item in this)得到的,然后作为lambda表达式的参数。
fun main(args: Array<String>) {    var ints = arrayListOf(1, 2, 3)    val doubled = ints.map { it * 2 }    println(doubled)}
3、下划线用于lambda中表示没用到的参数。
fun main(args: Array<String>) {    var map = mapOf(1 to "one", 2 to "two")    println(map.mapValues { (_, value) -> "$value" })//_代表没有用到的key}

4、高阶函数必须为函数类型的参数指定类型,该参数名可作为函数名使用。前面已经见到很多了,就不多说了。

5、可通过标签从lambda显示返回一个值,否则为最后一个表达式的值。

6、匿名函数作为参数时必须放在圆括号内,匿名函数与lambda表达式的区别是return时匿名函数从自身返回,而lambda表达式中的return将从包含它的函数返回。

7kotlinlambda表达式或者匿名函数(以及局部函数和对象表达式)可以访问外部作用域中声明的变量,类似于内部类。

8、类似于扩展函数,允许在函数体内访问接收者对象的成员而无需额外的限定符。匿名函数允许直接指定函数字面值的接收者类型。当接收者类型可以从上下文推断时,lambda表达式可以用作带接收者的函数字面值。。。(晕乎乎的,没懂

class HTML {    fun body() {        println("body")    }}fun html(init: HTML.() -> Unit): HTML {    val html = HTML() // 创建接收者对象    html.init() // 将该接收者对象传给该 lambda    return html}fun main(args: Array<String>) {    html {        // 带接收者的 lambda 由此开始        body() // 调用该接收者对象的一个方法    }}

9、内联函数能消除部分时间开销,减少部分效率损失,用inline标记。。。求清晰点的demo!

10noline修饰部分参数内联,求解释!求demo!

11、前面说了lambda表达式中的 return 将从包含它的函数返回,现在又来一句lambda表达式不能使包含他的函数返回,除非设置为内联。谁能告诉我为什么?我有一种把所有文章都删掉的冲动!我在想,我到底是来踩坑的还是来浪费大家时间的?

12、这种位于lambda表达式中,但退出包含它的函数,称为非局部返回。(有一种似懂非懂的感觉)

fun hasZeros(ints: List<Int>): Boolean {    ints.forEach {        if (it == 0) return true // 从 hasZeros 返回    }    return false}

13crossinline用来标记调用来自局部对象或者嵌套函数的内联函数。(看见demo也是懵逼的)

inline fun f(crossinline body: () -> Unit) {    val f = object: Runnable {        override fun run() = body()    }}

14、具体化的类型参数以及内联属性我已经无法描述出来了,神啊,救救我吧!

原创粉丝点击