先看下构建Map的函数mapOf
的使用
val map= mapOf(1 to "Apple",2 to "Orange")
这里我们使用了A to B
这样的语法结构构建键值对,其实to
并不是Kotlin中的关键字,之所以能这样使用是因为Kotlin中提供的infix
函数。infix函数并不难理解,只是把编程语言的语法规则稍微调整了下,A to B实际上等价于A.to(B),下面我们看下infix函数的用法,比如将"Hello World".startWith("Hello")
改成"Hello World" benginWith "Hello"
如何使用infix
函数实现呢?其实很简单,创建String.kt
文件,在其中创建benginWith
函数
infix fun String.beginWith(prefix: String) = startsWith(prefix)
其实我们就是创建了一个String
的扩展函数beginWith
用于判断字符串的开头是不是以指定参数开始的,其内部的实现由String类的startsWith()函数实现。但是加上infix
关键字后,beginWith
就变成了一个infix函数了。
这样我们调用beginWith()
就可以使用类似A to B
语法格式调用了。
"Hello World" beginWith "Hello"
上面的写法就是"Hello World" 调用beginWith()函数,并传入"Hello"参数,只不过infix函数的调用允许省略.
和括号
,所以我们可以使用更接近英文的语法来编写代码,增加代码的可读性。
infix函数使用起来很方便也很简单,但是它的使用是有限制的:
- 1、infix函数不能是顶层函数,但是将infix函数定义成某个类的成员函数或者使用扩展函数将其定义在某个类中。
- 2、infix函数的参数有且仅有一个参数,不允许有多个参数。
下面我们再看个比较复杂的例子,比如我们判断一个集合中是否包括某个元素,一般可以这么写:
val list= listOf<String>("Apple","Banana","Orange")
if(list.contains("Apple")){
}
下面看下使用infix函数来使代码更具可读性
infix fun <T> Collection<T>.has(t: T) =contains(t)
创建了一个Collection的扩展函数,Collection是所有集合的总借口,这样我们就能使用类似A to B
的语法格式来判断集合中是否含有指定元素的功能了,使用如下:
val list= listOf<String>("Apple","Banana","Orange")
if(list has "Apple"){
}
现在我们已经完全掌握了infix函数的使用了,这里看下A to B
中的to
函数的具体实现。
public infix fun <A, B> A.to(that: B): Pair<A, B> = Pair(this, that)
定义了一个A类的扩展函数,传入类型B的参数,返回一个Pair对象,所以A to B
其实就是创建并返回一个含有A、B的Pair对象,而mapOf()函数中接收的是一个Pair类型的可变参数列表。下面我们自己手动实现一下。
infix fun <A, B> A.with(b: B) = Pair(this, b)
这样我们就可以使用with()
函数实现to
的功能了
val map= mapOf<Int,String>(1 with "")
到此为止我们已经掌握了infix函数的使用了。