---
description: Kotlin 开发约定和最佳实践
globs: **/*.kt
alwaysApply: false
---

## Kotlin 开发规范

### 基本原则

- 优先使用类型推断，必要时显式声明类型提高可读性
- 避免使用 `Any`，创建具体的类型定义
- 优先使用 `val` 而非 `var`，保持不可变性
- 使用 Kotlin 的空安全特性，避免显式 null 检查
- 避免魔法数字，定义有意义的常量

### 命名规范

- **类和接口**：PascalCase (`UserRepository`, `PaymentService`)
- **函数和变量**：camelCase (`getUserById`, `isValid`)
- **常量和枚举值**：UPPER_SNAKE_CASE (`MAX_RETRY_COUNT`, `DEFAULT_TIMEOUT`)
- **包名**：全小写，使用点分隔 (`com.example.userservice`)
- **文件名**：PascalCase，与主要类名一致
- **布尔变量**：使用 `is`、`has`、`can`、`should` 前缀 (`isLoading`, `hasPermission`, `canDelete`)
- 使用完整单词而非缩写，确保拼写正确
  - 标准缩写除外：API、URL、HTTP、JSON 等
  - 常见缩写：id、ctx、req、res

### 函数设计

- 编写简短且单一目的的函数（建议 ≤20 行）
- 使用表达式函数简化单行返回：`fun square(x: Int) = x * x`
- 函数名以动词开头，体现其行为
- 优先使用高阶函数和扩展函数
- 使用命名参数提高可读性：`createUser(name = "John", age = 25)`
- 合理使用默认参数值，减少函数重载
- 通过早期返回和提取工具函数避免深层嵌套
- 使用单一抽象级别原则

### 类和数据结构

- **数据类**：用于纯数据承载，自动生成 `equals`、`hashCode`、`toString`
- **密封类**：用于有限状态表示，替代枚举的复杂场景
- **密封接口**：Kotlin 1.5+ 用于更灵活的类型层次
- **对象类**：用于单例模式和工具类
- **内联类**：用于类型安全的原始类型包装
- 优先使用组合而非继承
- 遵循 SOLID 原则
- 保持类的职责单一，避免过大的类（建议 ≤200 行，≤10 个公共方法）
- 不要滥用原始类型，将相关数据封装在复合类型中

### 空安全和错误处理

- 使用 `?.` 安全调用操作符
- 使用 `?:` Elvis 操作符提供默认值
- 使用 `!!` 操作符需要有充分理由并添加注释
- 优先使用 `Result` 类型处理可能失败的操作
- 对于异常情况使用具体的异常类型而非通用异常
- 避免在函数中进行数据验证，使用具有内部验证的类型

### 协程和异步编程

- 使用 `suspend` 函数处理异步操作
- 在合适的作用域中启动协程 (`viewModelScope`, `lifecycleScope`, `runBlocking`)
- 使用 `Flow` 处理数据流，`StateFlow`/`SharedFlow` 处理状态
- 避免 `GlobalScope`，始终使用结构化并发
- 合理使用协程上下文和调度器
- 使用 `async`/`await` 进行并发操作
- 正确处理协程取消和异常

### 集合和函数式编程

- 优先使用不可变集合 (`listOf`, `setOf`, `mapOf`)
- 使用函数式操作：`map`、`filter`、`reduce`、`fold`
- 合理使用序列 (`Sequence`) 处理大数据集或链式操作
- 使用作用域函数：`let`、`run`、`with`、`apply`、`also`
- 使用 `takeIf`、`takeUnless` 进行条件处理
- 对简单 lambda 使用 `it` 参数，复杂情况使用命名参数

### 泛型和类型系统

- 合理使用泛型约束和变型（`in`、`out`）
- 使用 `reified` 参数访问泛型类型信息
- 利用类型别名提高代码可读性：`typealias UserId = String`
- 使用内联函数优化高阶函数性能

### 可见性和封装

- 使用最小必要的可见性修饰符
- 优先使用 `internal` 而非 `public` 用于模块内部 API
- 使用 `private` 限制类内部实现细节
- 合理使用 `protected` 用于继承场景

### 测试规范

- 测试方法使用描述性命名：`should_return_user_when_valid_id_provided`
- 遵循 Arrange-Act-Assert 模式
- 清楚命名测试变量：`given...`、`when...`、`then...` 或 `input...`、`expected...`、`actual...`
- 为每个公共函数编写单元测试
- 使用测试替身（Mock、Stub）模拟依赖
- 为每个模块编写集成测试
- 遵循 Given-When-Then 约定编写行为测试

### 代码组织和架构

- 按功能而非类型组织包结构
- 将相关的类放在同一文件中（如密封类的子类）
- 合理使用扩展函数增强现有类型
- 声明接口定义契约，面向接口编程
- 使用依赖注入提高代码可测试性
- 遵循领域驱动设计原则

### 性能和资源管理

- 使用 `inline` 关键字优化高阶函数
- 合理使用 `lazy` 延迟初始化
- 注意避免内存泄漏，特别是在协程和回调中
- 使用 `use` 函数自动管理资源


