[筆記] 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