你需要懂的Kotlin开发技巧之六-灵析社区

德州安卓

1.尾递归优化

平常我们可能面临编写递归函数的场景,比如:

fun test5(n: Int): Int =
    if (n == 1) {
        1
    } else
        test5(n - 1)

每个方法都对应一个栈帧,方法的递归调用会导致方法栈深度过深,存在StackOvewFlow的风险。Kotlin中提供了尾递归特性进行优化:

tailrec fun test5(n: Int): Int =
    if (n == 1) {
        1
    } else
        test5(n - 1)

可以看到尾递归优化就是给方法增加tailrec,并且递归方法的调用要处于方法的尾部,反编译成java代码看下效果:

可以看到编译器对方法的递归调用进行了优化。

2.中缀方法infix的实战

中缀方法的修饰是给方法增加infix声明,并且方法参数只能声明一个,比如:

infix fun String.a(b: String) = "$this - $b"

下面我们通过一个案例讲解下:

我们平常肯定有一个这样的需求:传入文件路径String返回File类型

fun makeFile(parent: String, child: String): File {
    return File(parent, child)
}

这样写起来没什么问题,但是结合中缀函数我们可以实现更优雅的封装,如下:

infix fun String.div(child: String): File = File(this, child)

使用如下:

fun makeFile(parent: String, child: String): File = parent div child

其中parent div child就等价于File(this, child)的实现。

这样写起来还不是特别优雅,比如每次都得div来创建File对象,div写起来太麻烦了,而且可读性太差。

为了解决上面的两个问题,我们可以结合运算符重载operator进行更进一步优化,看下常见的运算符重载函数及对应运算符的映射关系:

其中有个div函数重载/运算符的,借助于这个我们对上面String转File的函数改造下:

infix operator fun String.div(child: String): File = File(this, child)

然后就可以这样使用:

fun makeFile(parent: String, child: String): File = parent / child

如上所见,直接使用parent / child就可以完成File的创建,而且/的可读性更高。

阅读量:1469

点赞量:0

收藏量:0