ZetCode

Kotlin infix 关键字

最后修改于 2025 年 4 月 19 日

Kotlin 的中缀表示法允许在没有点和括号的情况下调用函数。infix 关键字为某些函数启用了这种更简洁的语法。本教程通过示例深入探讨了 infix 关键字。

基本定义

Kotlin 中的 infix 关键字将一个函数标记为可以使用中缀表示法调用。中缀函数必须是成员函数或扩展函数。它必须只有一个参数,并且不能有默认值。

基本中缀函数

此示例演示了如何创建和使用一个简单的中缀函数。中缀表示法在某些情况下使代码更具可读性。

BasicInfix.kt
package com.zetcode

class Person(val name: String) {
    infix fun says(message: String) {
        println("$name says: $message")
    }
}

fun main() {
    val p = Person("John")
    
    // Regular call
    p.says("Hello")
    
    // Infix call
    p says "Hi"
}

在这里,我们在 Person 类中定义了一个中缀函数 says。我们可以通过两种方式调用它:传统的使用点表示法,或使用中缀表示法。中缀版本用英语读起来更自然。

中缀扩展函数

中缀函数也可以是扩展函数。这允许将中缀操作添加到现有类,而无需修改它们。

ExtensionInfix.kt
package com.zetcode

infix fun Int.add(x: Int): Int = this + x

fun main() {
    val sum1 = 5.add(3) // Regular call
    val sum2 = 5 add 3  // Infix call
    
    println(sum1) // Output: 8
    println(sum2) // Output: 8
}

此示例向 Int 添加了一个中缀扩展函数。该函数执行加法,但演示了如何创建中缀操作。两种调用方式都会产生相同的结果。

用于自定义 DSL 的中缀

中缀表示法对于创建特定于领域的语言 (DSL) 特别有用。它有助于使代码的阅读更像自然语言。

DslInfix.kt
package com.zetcode

class Recipe {
    infix fun add(ingredient: String) {
        println("Adding $ingredient")
    }
}

fun main() {
    val recipe = Recipe()
    
    recipe add "flour"
    recipe add "sugar"
    recipe add "eggs"
}

这个简单的食谱 DSL 使用中缀表示法使代码的阅读更像烹饪说明。每一行都清楚地说明了要添加到食谱中的成分。

与运算符重载一起使用中缀

中缀函数可以与运算符重载结合使用,以创建具有表现力的 API。此示例显示了一个自定义的向量加法运算。

OperatorInfix.kt
package com.zetcode

data class Vector(val x: Int, val y: Int) {
    infix fun plus(other: Vector): Vector {
        return Vector(x + other.x, y + other.y)
    }
}

fun main() {
    val v1 = Vector(1, 2)
    val v2 = Vector(3, 4)
    
    val v3 = v1 plus v2
    
    println(v3) // Output: Vector(x=4, y=6)
}

在这里,我们为 Vector 加法定义了一个中缀 plus 函数。中缀表示法使向量加法运算读起来很自然。结果是一个新 Vector,其分量被求和。

用于创建范围的中缀

Kotlin 的标准库使用中缀函数来创建范围。to 函数是中缀表示法的一个众所周知的例子。

RangeInfix.kt
package com.zetcode

fun main() {
    // Regular call
    val range1 = 1.rangeTo(5)
    
    // Infix call
    val range2 = 1..5
    val range3 = 1 to 5
    
    println(range1.toList()) // Output: [1, 2, 3, 4, 5]
    println(range2.toList()) // Output: [1, 2, 3, 4, 5]
    println(range3)         // Output: (1, 5)
}

这展示了在 Kotlin 中创建范围的不同方法。to 中缀函数创建一个 Pair,而 .. 创建一个范围。两者都使用中缀表示法,以便更简洁的语法。

用于布尔运算的中缀

中缀函数非常适合布尔运算,使条件更具可读性。此示例创建自定义逻辑运算。

BooleanInfix.kt
package com.zetcode

infix fun Boolean.and(other: Boolean): Boolean = this && other
infix fun Boolean.or(other: Boolean): Boolean = this || other

fun main() {
    val a = true
    val b = false
    
    val result1 = a and b
    val result2 = a or b
    
    println(result1) // Output: false
    println(result2) // Output: true
}

我们为 Boolean 定义了自定义的 andor 中缀函数。虽然 Kotlin 已经有这些运算符,但这演示了如何创建类似的操作。中缀表示法使逻辑清晰。

用于数学运算的中缀

中缀表示法可以使数学运算更具可读性,尤其对于自定义数字类型或复杂计算。

MathInfix.kt
package com.zetcode

data class Complex(val real: Double, val imag: Double) {
    infix fun plus(other: Complex): Complex {
        return Complex(real + other.real, imag + other.imag)
    }
}

fun main() {
    val c1 = Complex(1.0, 2.0)
    val c2 = Complex(3.0, 4.0)
    
    val sum = c1 plus c2
    
    println(sum) // Output: Complex(real=4.0, imag=6.0)
}

此示例显示了使用中缀表示法的复数加法。plus 函数分别添加实部和虚部。中缀调用使操作在视觉上清晰。

中缀函数的最佳实践

来源

Kotlin 中缀函数文档

本教程深入探讨了 Kotlin 的 infix 关键字,展示了如何创建和使用中缀函数。我们探讨了各种场景,包括 DSL、数学运算和布尔逻辑。正确使用中缀表示法可以使您的代码更具表现力和可读性。

作者

我叫 Jan Bodnar,是一位充满激情的程序员,拥有多年的编程经验。自 2007 年以来,我一直在撰写编程文章。到目前为止,我已经写了 1400 多篇文章和 8 本电子书。我拥有超过八年的编程教学经验。

列出 所有 Kotlin 教程