转载自:https://blog.csdn.net/baidu_39589150/article/details/110521319
目录
1. infix函数
先来温习一下A to B语法的用法:
fun main(){
val map = mapOf("Apple" to 1, "Banana" to 2, "Orange" to 3, "Pear" to 4, "Grape" to 5)
for ((fruit, number) in map) {
println("fruit is " + fruit + ", number is " + number)
}
}
/*
fruit is Apple, number is 1
fruit is Banana, number is 2
fruit is Orange, number is 3
fruit is Pear, number is 4
fruit is Grape, number is 5
*/
那么我们用到的to到底是个什么东西呢?to其实并不是一个关键字,而是依赖于Kotlin提供的一个高级语法糖特性infix函数实现的一种语法结构。依赖于这种语法糖,我们可以实现很多更加便捷的写法,例如我们要使用String类的startsWith()函数:
if("hello".startsWith("h")){
// do something
}
如果我们并不想以调用方法的形式来判断呢,我们可以这样来实现:
//1.在String中添加扩展方法beginWith,并用infix修饰
infix fun String.beginWith(s: String) = startsWith(s)
//2.使用
fun main() {
if("hello" beginWith "h"){
// do something
}
}
实现方法很简单,首先我们在String中添加扩展方法beginWith,具体实现就交给String自身的startsWith方法,并用infix修饰,然后我们就可以像写一个英语语句一样来使用beginWith了。
由此看来infix函数并不复杂,但是我们需要注意的是:
- infix函数不能定义为顶层函数,必须是某个类的成员函数,但是我们可以使用扩展函数的方式将它定义到某个类中。
- infix函数必须接收且只能接收一个参数,参数类型没有限制。
2. A to B语法
了解了infix函数,我们就可以来研究一下A to B语法到底是怎样实现的了,其实我们看源码就可以知道了:
public infix fun <A, B> A.to(that: B): Pair<A, B> = Pair(this, that)
- 1.使用泛型将to()方法定义到了类型A下,并且接收一个B类型参数。
- 2.创建并返回一个Pair对象。
其实A to B这样的语法就是得到了一个包含A,B数据的Pair对象,而如果我们看下源码可知,mapOf方法接收的正是Pair类型的可变参数列表
public fun <K, V> mapOf(vararg pairs: Pair<K, V>): Map<K, V> =
if (pairs.size > 0) pairs.toMap(LinkedHashMap(mapCapacity(pairs.size))) else emptyMap()
接下来我们就仿造to函数写一个my2函数:
public infix fun <A, B> A.my2(that: B): Pair<A, B> = Pair(this, that)
然后我们就可以使用自己的my2()来构建键值对了:
fun main(){
val map = mapOf("Apple" my2 1, "Banana" my2 2, "Orange" my2 3, "Pear" my2 4, "Grape" my2 5)
for ((fruit, number) in map) {
println("fruit is " + fruit + ", number is " + number)
}
}
/*
fruit is Apple, number is 1
fruit is Banana, number is 2
fruit is Orange, number is 3
fruit is Pear, number is 4
fruit is Grape, number is 5
*/