rokevin
移动
前端
语言
  • 基础

    • Linux
    • 实施
    • 版本构建
  • 应用

    • WEB服务器
    • 数据库
  • 资讯

    • 工具
    • 部署
开放平台
产品设计
  • 人工智能
  • 云计算
计算机
其它
GitHub
移动
前端
语言
  • 基础

    • Linux
    • 实施
    • 版本构建
  • 应用

    • WEB服务器
    • 数据库
  • 资讯

    • 工具
    • 部署
开放平台
产品设计
  • 人工智能
  • 云计算
计算机
其它
GitHub
  • Infix Function(中缀函数)

  • 1. 中缀函数(Infix Function)
    • 核心定义
    • 关键特征
    • 使用场景
    • 示例
    • 注意事项
  • 中缀函数
    • 中缀函数 vs 扩展函数:核心区别(维度不同)
    • 中缀函数的必备约束条件(无论是否为扩展函数)
    • 扩展函数使用中缀调用方式的示例(可行)
    • 非扩展函数的中缀函数(类成员函数)

Infix Function(中缀函数)

1. 中缀函数(Infix Function)

核心定义

用infix关键字修饰的函数,支持「省略点号和括号」的中缀调用语法(a func b),本质是一种语法糖。

关键特征

  • 必须是成员函数或扩展函数(不能是顶层函数);
  • 必须只有一个参数,且参数不能有默认值;
  • 调用时可省略点号和括号,用空格分隔调用者和参数,代码更简洁直观。

使用场景

适合表达「二元关系」的操作(如关联、匹配、运算、判断等),让代码更接近自然语言。

示例

// 示例1:扩展函数实现中缀函数(判断字符串是否以指定后缀结尾)
infix fun String.endsWithSuffix(suffix: String): Boolean {
    return this.endsWith(suffix)
}

// 示例2:成员函数实现中缀函数(自定义计算器加法)
class Calculator(val base: Int) {
    infix fun add(num: Int): Int {
        return base + num
    }
}

// 使用
fun main() {
    // 中缀调用扩展函数
    val str = "HelloKotlin"
    println(str endsWithSuffix "Kotlin") // true(等价于str.endsWithSuffix("Kotlin"))
    
    // 中缀调用成员函数
    val calc = Calculator(10)
    println(calc add 20) // 30(等价于calc.add(20))
}

注意事项

  • 中缀函数的优先级低于算术运算符、逻辑运算符,高于赋值运算符;
  • 避免滥用,仅在能提升代码可读性的二元关系场景使用。

中缀函数

扩展函数可以采用中缀函数的使用方式,但需要同时满足中缀函数的相关约束条件;中缀函数和扩展函数并非互斥概念,而是从两个不同维度对函数的分类。

  1. 中缀函数是「调用语法」特殊,扩展函数是「功能扩展」机制,二者不互斥、可叠加;
  2. 扩展函数可以用中缀方式调用,只需满足中缀函数的 4 个核心约束;
  3. 中缀函数的核心价值是简化二元关系操作的代码,扩展函数的核心价值是无侵入式扩展已有类功能;
  4. 中缀函数的两种存在形式:类成员函数、扩展函数(均需满足约束条件)。

中缀函数 vs 扩展函数:核心区别(维度不同)

两者的核心差异在于分类维度不同,这是理解两者关系的关键:

对比维度中缀函数(Infix Function)扩展函数(Extension Function)
核心定义一种函数调用语法的特殊形式,允许省略括号和点号,以更简洁的方式调用函数一种函数功能扩展的机制,允许在不修改原有类源码的前提下,为该类添加新的成员函数
分类维度从「函数的调用方式」维度划分从「函数的归属 / 扩展能力」维度划分
核心价值简化函数调用,让代码更具可读性(尤其适合二元关系操作,如关联、匹配等)扩展已有类的功能,避免继承的冗余,符合「开闭原则」
存在形式可作为类的成员函数,也可作为扩展函数(满足约束即可)可作为普通扩展函数,也可升级为中缀扩展函数(满足约束即可)

中缀函数的必备约束条件(无论是否为扩展函数)

要使用中缀语法调用函数,必须满足以下4 个严格约束,缺一不可:

  1. 必须是成员函数或扩展函数:普通的顶层函数(不属于任何类、也不是扩展函数)无法被声明为中缀函数;
  2. 必须只有一个参数:函数的参数列表中只能有一个参数,不能无参,也不能有多个参数;
  3. 参数不能有默认值:该唯一参数不允许指定默认值(避免调用时的歧义);
  4. 必须用 infix 关键字修饰:在函数声明前显式添加 infix 关键字,标记该函数支持中缀调用语法。

扩展函数使用中缀调用方式的示例(可行)

下面通过代码示例,展示如何将扩展函数声明为中缀函数,并用中缀语法调用:

// 1. 定义:扩展函数 + 中缀函数(满足所有中缀约束)
// 为 String 类扩展一个中缀函数,用于判断字符串是否以指定后缀结尾(简化版 endsWith)
infix fun String.endsWithSuffix(suffix: String): Boolean {
    return this.endsWith(suffix)
}

// 2. 调用方式对比
fun main() {
    val str = "HelloKotlin"
    val suffix = "Kotlin"
    
    // 方式1:普通扩展函数调用方式(点号+括号)
    val result1 = str.endsWithSuffix(suffix)
    println("普通调用结果:$result1") // 输出:普通调用结果:true
    
    // 方式2:中缀函数调用方式(省略点号和括号,直接用空格分隔)
    val result2 = str endsWithSuffix suffix
    println("中缀调用结果:$result2") // 输出:中缀调用结果:true
}

再举一个更典型的二元关系示例(集合关联):

// 为 List<Int> 扩展中缀函数,实现与另一个 List<String> 按索引关联
infix fun List<Int>.associateWithList(strList: List<String>): Map<Int, String> {
    val resultMap = mutableMapOf<Int, String>()
    for (i in indices) {
        if (i < strList.size) {
            resultMap[this[i]] = strList[i]
        }
    }
    return resultMap
}

fun main() {
    val nums = listOf(1, 2, 3)
    val words = listOf("A", "B", "C")
    
    // 中缀调用扩展函数,代码更简洁直观
    val associateMap = nums associateWithList words
    println(associateMap) // 输出:{1=A, 2=B, 3=C}
}

非扩展函数的中缀函数(类成员函数)

为了完整理解,这里给出类成员函数作为中缀函数的示例(对比扩展函数):

// 定义一个简单的类
class Calculator(val base: Int) {
    // 类成员函数声明为中缀函数(满足约束:单个参数、无默认值、infix修饰)
    infix fun add(num: Int): Int {
        return base + num
    }
}

fun main() {
    val calc = Calculator(10)
    
    // 中缀调用类成员函数
    val result = calc add 20
    println(result) // 输出:30
    
    // 等价于普通调用
    val result2 = calc.add(20)
    println(result2) // 输出:30
}
最近更新:: 2026/3/22 16:04
Contributors: luokaiwen