一、主要实现方式
1. Pair
/Triple
元组
- 用途:临时快速返回 2 或 3 个简单值,适用于简单场景
- 语法:
fun getStatus(): Pair<Int, String> { return Pair(200, "Success") // 等价于 200 to "Success" } // 解构接收 val (code, message) = getStatus()
- 优点:代码简洁,无需定义新类型
- 缺点:可读性差(无法通过属性名理解含义),难以扩展
2. 自定义数据类 (Data Class)
- 用途:结构化返回多个强类型属性,适合复杂场景
- 语法:
data class ApiResult( val code: Int, val message: String, val timestamp: Long = System.currentTimeMillis() ) fun getApiResult(): ApiResult { return ApiResult(200, "Success") }
- 优点:
- 语义明确(通过属性名自解释)
- 支持默认值、扩展性更强
- 自动生成
equals()
/hashCode()
/toString()
等方法
3. 密封类 (Sealed Class)
- 用途:明确限定可能的返回值类型,常用于状态或结果封装
- 语法:
sealed class DownloadResult { data class Success(val file: File, val size: Long) : DownloadResult() data class Error(val code: Int, val message: String) : DownloadResult() object Loading : DownloadResult() } fun downloadFile(): DownloadResult { // 返回具体子类实例 }
- 优点:
- 类型安全(
when
表达式可穷举所有分支) - 结合不同数据类型(如成功返回文件,失败返回错误码)
- 类型安全(
4. 解构声明 (Destructuring Declaration)
- 用途:将对象的属性直接解构为多个变量
- 语法:
// 数据类默认支持解构 data class Point(val x: Int, val y: Int) val point = Point(10, 20) val (x, y) = point // x=10, y=20 // 自定义解构逻辑(通过 componentN() 函数) class CustomResult(val code: Int, val msg: String) { operator fun component1() = code operator fun component2() = msg }
- 适用场景:快速获取多个属性值,无需通过对象访问
二、知识点深度解析
1. 可空性处理
fun findUser(): Pair<String, Int>? {
// 可能返回 null
}
// 安全调用 + 解构
val (name, age) = findUser() ?: return
2. 类型安全校验
密封类强制处理所有可能类型:
when (val result = downloadFile()) {
is DownloadResult.Success -> showFile(result.file)
is DownloadResult.Error -> showError(result.code)
DownloadResult.Loading -> showProgress()
}
3. 性能对比
Pair
/Triple
:轻量级,适用于高频调用- 数据类:内存略高,但可通过
val
不可变性优化
三、最佳实践建议
场景 |
推荐方式 |
理由 |
---|---|---|
临时返回两个值 |
|
快速实现,无需额外类型 |
API 响应封装 |
数据类 |
明确字段含义,易扩展 |
状态机/结果流 |
密封类 |
强制处理所有分支,类型安全 |
高频简单操作 |
解构声明 |
简化代码,提升可读性 |
四、实战案例
网络请求结果封装
sealed class NetworkResult<out T> {
data class Success<T>(val data: T) : NetworkResult<T>()
data class Error(val code: Int, val message: String) : NetworkResult<Nothing>()
object Loading : NetworkResult<Nothing>()
}
fun fetchData(): NetworkResult<String> {
return try {
NetworkResult.Success("Data loaded")
} catch (e: Exception) {
NetworkResult.Error(500, "Server error")
}
}
// 使用
when (val result = fetchData()) {
is NetworkResult.Success -> println(result.data)
is NetworkResult.Error -> println("Error: ${result.code}")
NetworkResult.Loading -> showProgress()
}
通过选择合适的多返回值模式,可以显著提升代码的健壮性和可维护性。