平常我们可能面临编写递归函数的场景,比如:
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代码看下效果:
可以看到编译器对方法的递归调用进行了优化。
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