关于 kotlin-functions
面向 Kotlin 开发者的编码技能,用于判断函数应归属何处,以及采用成员函数、顶层函数、工厂、协作者还是扩展函数。它优先考虑语义归属与兼容性,而非流畅语法。
主要功能
- 01识别语义归属
- 02排除误导性的扩展接收者
- 03选择合适的函数形式
- 04迁移实现并更新调用方
- 05检查可见性与兼容性
- 06编译并测试变更
适用场景
- 01审查 Kotlin 扩展函数
- 02重构放置不当的构造或解析逻辑
- 03选择成员函数或协作者
- 04检查函数 API 变更的兼容性
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ chrisbanes/ skills --skill kotlin-functions安装后在 Claude Code 中输入/kotlin-functions确认已加载。
详细介绍
Kotlin 函数归属
核心原则
将函数放在语义上最准确且范围最小的归属方中。扩展语法会改变调用形式,但不会改变归属。
默认拒绝定义在原始类型、通用类型和库所有类型上的扩展:它们会造成归属错位、领域污染、补全和导入噪声,以及命名冲突。
流程
按顺序执行。
1. 明确语义归属方
说清操作是什么,以及哪个概念拥有它。如果归属不明确,请先停止,不要选择语法形式。
2. 尽早拒绝容易误导的接收者
对于 String、原始类型、集合、Flow、框架或第三方类型的接收者,必须满足全部条件:
- 限定在紧密关联的
private/internal作用域内。 - 对接收者的所有取值都有效。
- 不涉及策略、状态、I/O 或依赖。
- 接收者语法能显著提升清晰度。
- 不存在更合适的项目自有归属方。
任一条件不满足,都不得在该接收者上定义扩展;应在第 3 步中选择非扩展形式。private fun <T> MutableList<T>.swap(...) 可以通过:它属于列表本身,不涉及策略,且仅用于算法内部。
3. 选择函数形式
| 含义 | 优先选择 |
|---|---|
| 项目自有类型的内在行为 | 成员函数 |
| 跨类型的无状态操作 | 顶层函数 |
| 构造或解析 | 目标类型的工厂函数或具名顶层函数 |
| 持有策略、状态、I/O、时钟、本地化设置或依赖 | 注入的服务/协作者 |
| 类型原生操作,且接收者形式更清晰并通过第 2 步的所有检查 | 扩展函数 |
只有当行为需要持有策略、状态、I/O、时钟/本地化设置或依赖时,才使用服务/协作者;否则,无状态函数应使用显式参数。
4. 迁移行为和调用方
迁移实现,然后更新调用、导入和函数引用。除非这是明确的破坏性版本发布,否则应保留或弃用公共入口;仅在有具体使用方时添加非公共迁移支持。
// Before: String falsely owns UserId construction.
fun String.toUserId(): UserId = UserId(this)
// After: UserId owns construction.
@JvmInline
value class UserId private constructor(val value: String) {
companion object {
fun parse(raw: String): UserId = UserId(raw)
}
}
val id = UserId.parse(raw)
5. 验证并完成
无论采用哪种形式,都要检查可见性、导入、冲突和兼容性。对于扩展函数,还要检查可空接收者、泛型和未来成员的优先级。编译并测试;如果失败,请缩小 API 范围或返回第 1 步。
常见辩解
| “但是……” | 回应 |
|---|---|
| 链式语法 | 可读性不会产生归属权。 |
| Kotlin 使用扩展函数 | 惯用写法仍需符合准确的语义。 |
| 它是 private/internal | 只有通过所有检查,作用域才有帮助。 |
| 工具对象更糟 | 使用顶层函数或目标类型的工厂函数。 |
| 默认策略很明显 | 时区/本地化默认值属于策略;应明确保留。 |
| 已经在 PR 里了 | 现有代码不能证明归属正确。 |
警示信号
- 在
String、数字、集合、Flow或供应商类型上承载领域含义。 - 扩展函数隐藏时钟、本地化设置、I/O、策略或依赖。
常见错误
| 错误 | 修正方式 |
|---|---|
Long.toDisplayDate() | 格式化器负责时区/本地化策略。 |
| 扩展函数隐藏解析逻辑 | 使用 Type.parse(raw) 或具名解析器。 |
| 公共的库类型扩展 | 根据步骤 1–3 重新归类。 |
相关内容
评论
支持 Markdown