首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

一文带你了解 Kotlin infix 函数的基本用法和使用场景

  • 25-04-18 23:22
  • 3336
  • 14018
juejin.cn

infix 是 Kotlin 中的一个特殊关键字,它允许我们以更自然、更可读的方式调用只有一个参数的函数。这种函数调用方式去掉了传统的点号和括号,使代码更加简洁流畅。

一、基本概念与语法

1.1 什么是 infix 函数

infix 函数是满足以下条件的成员函数或扩展函数:

  1. 必须只有一个参数
  2. 不能接受可变参数
  3. 不能有默认参数值

1.2 基本语法

kotlin
代码解读
复制代码
infix fun 接收者类型.函数名(参数: 参数类型): 返回类型 { // 函数体 }

二、基本用法示例

2.1 自定义 infix 函数

kotlin
代码解读
复制代码
class Person(val name: String) { infix fun say(message: String) { println("$name says: $message") } } fun main() { val alice = Person("Alice") // 常规调用 alice.say("Hello") // 输出: Alice says: Hello // infix 调用 alice say "Hi" // 输出: Alice says: Hi }

2.2 扩展函数作为 infix 

kotlin
代码解读
复制代码
infix fun Int.add(other: Int): Int = this + other fun main() { println(5 add 3) // 输出: 8 }

三、标准库中的 infix 函数

Kotlin 标准库中已经定义了一些有用的 infix 函数:

3.1 to 函数(创建 Pair)

kotlin
代码解读
复制代码
fun main() { val pair1 = "key" to "value" // 等价于 Pair("key", "value") val pair2 = 1 to 2 println(pair1) // 输出: (key, value) println(pair2) // 输出: (1, 2) }

3.2 范围操作

kotlin
代码解读
复制代码
fun main() { val range1 = 1 until 10 // 1..9 val range2 = 'a'..'z' println(5 in range1) // true println('A' in range2) // false }

3.3 位运算

kotlin
代码解读
复制代码
fun main() { val flags = 0b1010 val mask = 0b1100 println(flags and mask) // 8 (0b1000) println(flags or mask) // 14 (0b1110) println(flags xor mask) // 6 (0b0110) }

四、实用场景

4.1 DSL 构建

kotlin
代码解读
复制代码
class Html { private val children = mutableListOf() infix fun String.`class`(value: String) { children.add("$this class=\"$value\"") } override fun toString(): String = children.joinToString("\n") } fun html(init: Html.() -> Unit): Html { val html = Html() html.init() return html } fun main() { val page = html { "div" `class` "container" "span" `class` "text-primary" } println(page) /* 输出: div class="container" span class="text-primary" */ }

4.2 测试断言

kotlin
代码解读
复制代码
infix fun T.shouldBe(expected: T) { if (this != expected) { throw AssertionError("Expected $expected but was $this") } } fun main() { val result = 3 * 7 result shouldBe 21 // 通过 // result shouldBe 20 // 抛出 AssertionError }

4.3 数学表达式

kotlin
代码解读
复制代码
infix fun Int.pow(exponent: Int): Int { return when { exponent < 0 -> throw IllegalArgumentException("Negative exponent") exponent == 0 -> 1 else -> this * this.pow(exponent - 1) } } fun main() { println(2 pow 10) // 1024 }

五、注意事项

5.1 优先级规则

infix 函数调用的优先级低于算术运算符,但高于布尔运算符和比较运算符:

kotlin
代码解读
复制代码
fun main() { println(1 + 2 pow 3) // 等价于 1 + (2 pow 3) = 9 println(2 pow 3 + 1) // 等价于 (2 pow 3) + 1 = 9 }

5.2 与操作符重载的区别

特性infix 函数操作符重载
语法自定义名称固定操作符集
参数数量必须一个参数根据操作符决定
调用方式空格分隔符号操作符
使用场景提高可读性数学/逻辑运算

5.3 限制与陷阱

  1. 不能与保留关键字冲突:
kotlin
代码解读
复制代码
// 错误:is 是保留关键字 // infix fun String.is(other: String) = this == other // 解决方案:使用反引号转义 infix fun String.`is`(other: String) = this == other
  1. 避免过度使用:
kotlin
代码解读
复制代码
// 不推荐 - 可读性差 val result = data process filter apply transformation // 推荐 - 适当使用传统调用方式 val result = data.process().filter().apply(transformation)
  1. 类型安全:
kotlin
代码解读
复制代码
infix fun String.repeat(count: Int): String = this.repeat(count) fun main() { // 编译错误:类型不匹配 // "a" repeat "3" // 正确 "a" repeat 3 }

六、高级技巧

6.1 结合扩展属性

kotlin
代码解读
复制代码
val Int.ms get() = this val Int.seconds get() = this * 1000 infix fun Int.after(unit: Int) = System.currentTimeMillis() + this * unit fun main() { val futureTime = 10 seconds after System.currentTimeMillis() println("Future timestamp: $futureTime") }

6.2 链式调用

kotlin
代码解读
复制代码
class Query { private val conditions = mutableListOf() infix fun where(condition: String) = apply { conditions.add(condition) } override fun toString(): String = conditions.joinToString(" AND ") } fun main() { val query = Query() where "age > 18" where "name = 'Alice'" println(query) // 输出: age > 18 AND name = 'Alice' }

6.3 类型安全构建器

kotlin
代码解读
复制代码
class Route { private val path = mutableListOf() infix fun String.to(next: String) = apply { path.add(this) path.add(next) } fun build(): String = path.joinToString(" -> ") } fun main() { val route = Route() "Home" to "Products" to "Cart" to "Checkout" println(route.build()) // 输出: Home -> Products -> Cart -> Checkout }

七、与 Java 互操作

7.1 Java 调用 Kotlin infix 函数

kotlin
代码解读
复制代码
// ---- Kotlin ---- class Calculator { infix fun add(x: Int) = this + x }
java
代码解读
复制代码
// ---- Java ---- public class JavaClient { public static void main(String[] args) { Calculator calc = new Calculator(); // 只能使用常规调用方式 int result = calc.add(5); } }

7.2 替代方案

对于需要 Java 和 Kotlin 都友好的 API:

kotlin
代码解读
复制代码
class Api { // 常规函数 fun connect(host: String) { /*...*/ } // infix 别名 infix fun to(host: String) = connect(host) } // Kotlin 中两种方式都可以 Api().to("example.com") Api().connect("example.com") // Java 中只能使用 connect()

八、最佳实践

  1. 命名原则:

    • 使用动词-名词或名词-动词形式(如 user assignTo project)
    • 避免使用过于通用的名称(如 do、make)
  2. 适用场景:

    • 自然语言风格的 DSL
    • 数学/逻辑表达式
    • 测试断言
    • 简单的二元关系表达
  3. 避免场景:

    • 复杂逻辑(超过简单操作)
    • 需要多个参数的函数
    • 性能关键路径(infix 有轻微性能开销)
  4. 文档规范:

    kotlin
    代码解读
    复制代码
    /** * Connects this user to the specified project * @param project the target project * @return the assignment record */ infix fun User.assignTo(project: Project): Assignment

九、总结

Kotlin 的 infix 函数是一个强大的语法糖,它:

  1. 提高了特定场景下的代码可读性
  2. 支持创建流畅的 DSL
  3. 与扩展函数结合能极大增强表达能力

使用时应当:

  • 保持函数功能简单明确
  • 注意优先级规则
  • 避免过度使用导致代码难以理解
  • 为 Java 调用者提供替代方案

合理使用 infix 函数可以让你的 Kotlin 代码更加简洁优雅,特别是在构建领域特定语言(DSL)和测试框架时非常有用。

更多分享

  1. 一文吃透Kotlin中冷流(Clod Flow)和热流(Hot Flow)
  2. 一文带你吃透Kotlin协程的launch()和async()的区别
  3. Kotlin 委托与扩展函数——新手入门
  4. Kotlin 作用域函数(let、run、with、apply、also)的使用指南
  5. 一文带你吃透Kotlin中 lateinit 和 by lazy 的区别和用法
  6. Kotlin 扩展方法(Extension Functions)使用详解
  7. Kotlin 中 == 和 === 的区别
  8. Kotlin 操作符与集合/数组方法详解——新手指南
  9. Kotlin 中 reified 配合 inline 不再被类型擦除蒙蔽双眼
  10. Kotlin Result 类型扩展详解 —— 新手使用指南
注:本文转载自juejin.cn的QING618的文章"https://juejin.cn/post/7492271537011130387"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

140
Android
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2024 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top