美文网首页
Android:Kotlin详细入门学习指南-高阶函数-基础语法

Android:Kotlin详细入门学习指南-高阶函数-基础语法

作者: 拖鞋王子猪 | 来源:发表于2021-02-08 15:23 被阅读0次

    本人也是在初学Kotlin,如有错误,请帮忙指出,持续更新

    Android:Kotlin详细入门学习指南-高阶函数-基础语法(七)

    建议先看看前面的文章
    Android:Kotlin详细入门学习指南-基础语法(一)

    Android:Kotlin详细入门学习指南-基本类型-基础语法(二)

    Android:Kotlin详细入门学习指南-包-控制流-返回与跳转-基础语法(三)

    Android:Kotlin详细入门学习指南-类和对象-基础语法(四)

    Android:Kotlin详细入门学习指南-类和对象(下)-基础语法(五)

    Android:Kotlin详细入门学习指南-函数-基础语法(六)

    这篇文章分享的内容比较多,建议先关注收藏,再查看,以免迷路

    高阶函数

    高阶函数就是可以接受函数作为参数并返回一个函数的函数

    字面函数和函数表达式

    字面函数或函数表达式就是一个 "匿名函数",也就是没有声明的函数,但立即作为 表达式传递下去。

    max(strings, {a, b -> a.length < b.length })
    

    max 函数就是一个高阶函数,它接受函数作为第二个参数。第二个参数是一个表达 式所以本生就是一个函数,即字面函数。作为一个函数,相当于:

    fun compare(a: String, b: String) : Boolean = a.length < b.lengt h
    
    函数类型

    一个函数要接受另一个函数作为参数,我们得给它指定一个类型。

    fun max<T>(collection: Collection<out T>, less: (T, T) -> Boolean ): T? { 
        var max: T? = null 
        for (it in collection) 
            if (max == null || less(max!!, it)) 
                max = it 
                return max 
    }
    

    参数 less 是 (T, T) -> Boolean 类型,也就是接受俩个 T 类型参数返回一 个 Boolean :如果第一个参数小于第二个则返回真。 在函数体第四行, less 是用作函数

    val compare: (x: T,y: T) -> Int = ...
    
    函数文本语法
    val sum = {x: Int,y: Int -> x + y}
    

    函数文本总是在大括号里包裹着,在完全语法中参数声明是在括号内,类型注解是 可选的,函数体是在 -> 之后,像下面这样:

    val sum: (Int, Int) -> Int = {x, y -> x+y }
    函数文本有时只有一个参数。如果 kotlin 可以从它本生计算出签名,那么可以省略 这个唯一的参数,并会通过 it 隐式的声明它:
    
    ```kotlin
    ints.filter {it > 0}//这是 (it: Int) -> Boolean 的字面意思
    

    注意如果一个函数接受另一个函数做为最后一个参数,该函数文本参数可以在括号 内的参数列表外的传递。

    函数表达式

    上面没有讲到可以指定返回值的函数。在大多数情形中,这是不必要的,因为返回 值是可以自动推断的。然而,如果你需要自己指定,可以用函数表达式来做:

    fun(x: Int, y: Int ): Int = x + y
    
    闭包

    一个字面函数或者表达式函数可以访问闭包,即访问自身范围外的声明的变量。不 像 java 那样在闭包中的变量可以被捕获修改:

    var sum = 0 ins filter {it > 0} forEach { 
        sum += it 
    }
    print(sum)
    
    内联函数

    inline 标记即影响函数本身也影响传递进来的 lambda 函数:所有的这些都将被 关联到调用点。 内联可能会引起生成代码增长,但我们可以合理的解决它(不要内联太大的函数)

    inline fun lock<T>(lock: Lock,body: ()-> T): T { //... }
    

    为了你想要一些 lambda 表达式传递给内联函数时是内联的,你可以给你的一些函 数参数标记 @noinline 注解:

    inline fun foo(inlined: () -> Uint, @noinline notInlined: () -> Unit) { //... }
    

    内联的 lambda 只能在内联函数中调用,或者作为内联参数,但 @noinline 标记 的可以通过任何我们喜欢的方式操控:存储在字段,( passed around etc)

    返回到非局部

    在 kotlin 中,我们可以不加条件的使用 return 去退出一个命名函数或表达式函 数。这意味这退出一个 lambda 函数,我们不得不使用标签,而且空白的 return 在 lambda 函数中是禁止的,因为 lambda 函数不可以造一个闭合函数返回:

    fun foo() { 
        ordinaryFunction { 
            return // 错误 不可以在这返回 
            } 
    }
    

    但如果 lambda 函数是内联传递的,则返回也是可以内联的,因此允许下面这样:

    fun foo() { 
        inlineFunction { 
            return // 
            ] 
    }
    

    注意有些内联函数可以调用传递进来的 lambda 函数,但不是在函数体,而是在另 一个执行的上下文中,比如局部对象或者一个嵌套函数。在这样的情形中,非局部 的控制流也不允许在lambda 函数中。
    内联 lambda 不允许用 break 或 continue ,但在以后的版本可能会支持。

    实例化参数类型

    有时候我们需要访问传递过来的类型作为参数:

    fun <T> TreeNode.findParentOfType(clazz: Class<T>): T? { 
        var p = parent 
        while (p != null && !clazz.isInstance(p)) { 
            p = p?.parent 
        }
        @suppress("UNCHECKED_CAST") 
        return p as T 
    }
    

    现在,我们创立了一颗树,并用反射检查它是否是某个特定类型。一切看起来很 好,但调用点就很繁琐了:

    myTree.findParentOfType(javaClass<MyTreeNodeType>() )
    

    我们想要的仅仅是给这个函数传递一个类型,即像下面这样:

    myTree.findParentOfType<MyTreeNodeType>()
    

    为了达到这个目的,内联函数支持具体化的类型参数,因此我们可以写成这样:

    inline fun <reified T> TreeNode.findParentOfType(): T? { 
        var p = parent 
        while (p != null && p !is T) { 
            p = p?.parent 
        }
        return p as T 
    }
    

    用 refied 修饰符检查类型参数,既然它可以在函数内部访问了,也就基本上接 近普通函数了。因为函数是内联的,所以不许要反射,像 !is `as`这样的操作 都可以使用。同时,我们也可以像上面那样调用它了

    myTree.findParentOfType<MyTreeNodeType>()
    

    尽管在很多情况下会使用反射,我们仍然可以使用实例化的类型参数 javaClass() 来访问它:

    inline fun methodsOf<reified T>() = javaClass<T>().getMethods()
    fun main(s: Array<String>) {
    println(methodsOf<String>().joinToString('\n'))
    }

    普通的函数(没有标记为内联的)不能有实例化参数。

    这篇文章主要分享Kotlin中的高阶函数.

    本人也是在初学Kotlin,如有错误,请帮忙指出,持续更新

    相关文章

      网友评论

          本文标题:Android:Kotlin详细入门学习指南-高阶函数-基础语法

          本文链接:https://www.haomeiwen.com/subject/swzxxltx.html