《Kotlin核心编程》 ——2.4.6 中缀表达式
2.4.6 中缀表达式
本节中,我们已经见识了不少Kotlin中奇特的方法,如in、step、downTo、until,它们可以不通过点号,而是通过中缀表达式来被调用,从而让语法变得更加简洁直观。那么,这是如何实现的呢?
先来看看Kotlin标准库中另一个类似的方法to的设计,这是一个通过泛型实现的方法,可以返回一个Pair。
infix fun <A, B> A.to(that: B): Pair<A, B>
在Kotlin中,to这种形式定义的函数被称为中缀函数。一个中缀函数的表达形式非常简单,我们可以理解成这样:
A 中缀方法 B
不难发现,如果我们要定义一个中缀函数,它必须需满足以下条件:
该中缀函数必须是某个类型的扩展函数或者成员方法;
该中缀函数只能有一个参数;
虽然Kotlin的函数参数支持默认值,但中缀函数的参数不能有默认值,否则以上形式的B会缺失,从而对中缀表达式的语义造成破坏;
同样,该参数也不能是可变参数,因为我们需要保持参数数量始终为1个。
函数可变参数
Kotlin通过varargs关键字来定义函数中的可变参数,类似Java中的“…”的效果。需要注意的是,Java中的可变参数必须是最后一个参数,Kotlin中没有这个限制,但两者都可以在函数体中以数组的方式来使用可变参数变量,正如以下例子:
fun printLetters(vararg letters: String, count: Int): Unit {
print("${count} letters are ")
for (letter in letters) print(letter)
}
>>> printLetters("a", "b", "c", count = 3)
3 letters are abc
此外,我们可以使用*(星号)来传入外部的变量作为可变参数的变量,改写如下:
val letters = arrayOf("a", "b", "c")
>>> printLetters(*letters, count = 3)
3 letters are abc
由于to会返回Pair这种键值对的结构数据,因此我们经常会把它与map结合在一起使用。如以下例子:
mapOf(
1 to "one",
2 to "two",
3 to "three"
)
可以发现,中缀表达式的方式非常自然。接下来,我们再来自定义一个中缀函数,它是类Person中的一个成员方法:
class Person {
infix fun called(name: String) {
println("My name is ${name}.")
}
}
因为called方法用infix进行了修饰,所以我们可以这样调用它:
fun main(args: Array<String>) {
val p = Person()
p called "Shaw"
}
// 运行结果
My name is Shaw.
需要注意的是,Kotlin仍然支持使用普通方法的语法习惯来调用一个中缀函数。如这样来执行called方法:
p.called("Shaw")
然而,由于中缀表达式在形式上更像自然语言,所以之前的语法要显得更加的优雅。
- 点赞
- 收藏
- 关注作者
评论(0)