Kotlin标准库 Result<T,E> 简介与应用


错误处理

程序设计,尤其是软件工程中,处理错误是不可避免的,比较常见的方式有以下种:

  • if(f() == null) 手动判断方式
  • try {} catch(Exception) {} 异常(Exception)方式
  • Result 方式

他们各有各自的优缺点

Kotlin Result

Kotlin的Result定义在Kotlin标准库中,无需额外导入库,其源码在这里可查看 stdlib/src/kotlin/util/Result.kt

创建Result

常用Result作为函数返回值

直接创建

例:

// 如果成功,则返回OK123456,否则返回错误(及其Exception)
fun f()
{
	var f: Result = Result.failure(Exception()) // 通过 failure 或 success 创建Result
	var s: Result = Result.success("OK123456")  // 通过 failure 或 success 创建Result
	return s
}

从Try-Catch方法转换

Result.runCatching函数可将Try-Catch方法转换为Result

val y: Result = Result.runCatching {
	throw Exception()
    1
}

// y == Result.failure(Exception())

解析Result

更多的时候是获得一个Result,据其是success还是failure进行下一步操作,在这里有很多方法

getOr系列函数

包括

result.getOrNull() //返回一个可空类型,若失败则为空,否则为value,更适合喜欢 if(f() == null) 的人
result.getOrThrow() // 若失败,则抛出异常,更适合喜欢Exception方式的人
result.getOrDefault(defaultValue) // 若失败,则返回defaultValue参数

通过isSuccess判断 (不推荐)

展开 这种方式适合喜欢 if(f() == null) 的人,注意getOrNull返回的仍然是可空类型

val result: Result = f()
if(result.isSuccess) {
	val x = result.getOrNull();
} else {

}

fold函数

fold函数可将错误处理的方式一并写入,适合较为简单的错误处理

val result: Result = f()
val x: String = result.fold(
        onSuccess = { "f() OK" },
        onFailure = { "f() Failed" }
	)
println(x)

处理Result

可使用map函数在不取出Result值的情况下对Result进行变换

var s = Result.success("OK123456")
s = s.map { it.substring(1..3) }

// s == Result.success("K12")

其他函数

其他诸如 recover,mapCatching,getOrElse之类的函数,只是上面几种的变体

小结

  • 可使用 Result.success(value)Result.failure(Exception()) 创建 Result
  • 可使用 getOr系列函数或fold函数 解析Result
  • 可使用 map 函数处理Result, runCatching 函数从 Exception 方式转换为 Result