[笔记] Kotlin标准库 Result


错误处理

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

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

他们各有各自的优缺点

Kotlin Result<T>

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

创建Result

常用Result作为函数返回值

直接创建

例:

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

从Try-Catch方法转换

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

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

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

解析Result

更多的时候是获得一个Result<T>,据其是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<String> = 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之类的函数,只是上面几种的变体

实现

sealed class Maybe<out T> {
    object None                   :Maybe<Nothing>()
    class Just<out T>(val x :T)   :Maybe<T>()
}

fun <T,R> Maybe<T>.fmap(transform :(T) -> Maybe<R>) = when(this) {
    Maybe.None -> Maybe.None
    is Maybe.Just -> transform(this.x)
}

在C/C++中,可以使用std::variantunion: C++小技巧 实现Kotlin中的Result

小结

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


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM