Kotlin学习 7 -- infix函数
SUMMER DAY (图片来源于网络)本篇文章主要介绍以下几个知识点:
- 使用 infix 函数构建更可读的语法
内容参考自第一行代码第3版
在前面的学习中,使用过 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)
本篇文章就介绍到这。