美文网首页kotlinkotlinKotlin学习
Kotlin学习 7 -- infix函数

Kotlin学习 7 -- infix函数

作者: 开心wonderful | 来源:发表于2020-07-10 16:03 被阅读0次

    本篇文章主要介绍以下几个知识点:

    SUMMER DAY (图片来源于网络)

    在前面的学习中,使用过 A to B 这样的语法结构构建键值对。这种语法结构可读性高,更接近于用英语的语法来编写程序。

    上面的 to 并不是 Kotlin 语言中的关键字,之所以能使用 A to B 这样是因为 Kotlin 提供了一种高级语法糖特性:infix 函数

    infix 函数只是把编程语言函数调用的语法规则调整了一下而已,如 A to B 其实等价于 A.to(B)的写法。

    举个栗子,String 类中的 startsWith() 函数:

    if("Hello Wonderful".startsWith("Hello")) {
        // to do something
    }
    

    上面startsWith() 函数的用法简单,若借助 infix 函数则可以用一种更具可读性的语法来表达。

    在创建 String 类的扩展函数 beginsWith() 的前面加上关键字 infix 如下:

    infix fun String.beginsWith(prefix: String) = startsWith(prefix)
    

    这样 beginsWith() 函数就变成了一个 infix 函数,调用方式如下:

    if ("Hello Wonderful" beginsWith "Hello"){
        // to do something
    }
    

    另外,infix 函数有两个较严格的限制:

    • infix 函数是不能定义成顶层函数的,它必须是某个类的成员函数,可以用扩展函数的方式将它定义到某个类中。

    • infix 函数必须接收且只能接收一个参数,参数类型不限制。


    下面举个稍微复杂的栗子,比如一个集合:

    val list = listOf("apple", "orange", "pear")
    if (list.contains("orange")) {
        // to do something
    }
    

    借助 infix 函数并给 Collection 接口添加一个扩展函数 has() 如下:

    infix fun <T> Collection<T>.has(element: T) = contains(element)
    

    这样就可以用如下语法来判断集合中是否包括某个指定的元素:

    val list = listOf("apple", "orange", "pear")
    if (list has "orange") {
        // to do something
    }
    

    接下来思考下 mapOf() 函数中允许使用 A to B 的语法结构来构建键值对,是如何实现的呢?

    直接看下 to() 的源码如下:

    public infix fun <A, B> A.to(that: B): Pair<A, B> = Pair(this, that)
    

    可以看到,用定义泛型函数的方式将 to() 函数定义到了 A 类型下,并接收一个 B 类型参数,创建并返回一个 Pair 对象。

    也就是说 A to B 实际上得到的是一个包含 A、B 数据的 Pair 对象,而 mapOf() 函数接收的正是一个 Pair 类型的可变参数列表。

    当然,也可以模仿 to() 函数的源码来编写一个自己的键值对构建函数:

    infix fun <A, B> A.with(that: B): Pair<A, B> = Pair(this, that)
    

    with() 函数构建的键值对传入 mapOf() 方法中:

    val map = mapOf("name" with "wonderful", "age" with 18)
    

    本篇文章就介绍到这。

    相关文章

      网友评论

        本文标题:Kotlin学习 7 -- infix函数

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