Does Kotlin have a Result type like Swift
There are multiple implementations, but the two that I'm aware of (and that I know to be actively maintained) are:
- Kotlin-result - straight up result type, usefully flexible (there are references to other implementations in the README.md)
- Either in Arrow - a Kotlin implementation of Either which can be used as a result. (Arrow has lots of interesting functional stuff)
I don't know whether Kotlin has something like that but here is an implementation that should do the same:
sealed class Result<out Success, out Failure>
data class Success<out Success>(val value: Success) : Result<Success, Nothing>()
data class Failure<out Failure>(val reason: Failure) : Result<Nothing, Failure>()
Actual example:
fun echoString(string : String) : Result<String, Exception> {
return if (string.isEmpty()) {
Failure(Exception("Error"))
} else {
Success(string)
}
}
fun main(args : Array<String>) {
when(val result = echoString("string")) {
is Success -> println(result.value)
is Failure -> println(result.reason)
}
}
Kotlin has Result with properties such as isFailure and isSuccess which basically equivalent to Result of Swift.
Summary
Result, a type in the Kotlin standard library that is effectively a discriminated union between successful and failed outcome of execution of Kotlin function — Success T | Failure Throwable, where Success T represents a successful result of some type T and Failure Throwable represents a failure with any Throwable exception. For the purpose of efficiency, we would model it as a generic inline class Result in the standard library.
Limitation
Result cannot be used as a direct result type of Kotlin functions, properties of Result type are also restricted: e.g.
fun findUserByName(name: String): Result<User> // ERROR: 'kotlin.Result' cannot be used as a return type
fun foo(): Result<List<Int>> // ERROR
fun foo(): Result<Int>? // ERROR
var foo: Result<Int> // ERROR
However, functions that use Result type in generic containers or receive result as a parameter type are allowed:
fun findIntResults(): List<Result<Int>> // Ok
fun receiveIntResult(result: Result<Int>) // Ok
Usage(run online):
class NumberNotEvenException(var number: Int) : Exception("$number not even")
fun checkEvenNumbers(list: List<Int>): List<Result<Int>>{
var returnList = mutableListOf<Result<Int>>()
for (number in list){
if (number%2==0){
returnList.add(Result.success(number))
}else{
returnList.add(Result.failure(NumberNotEvenException(number)))
}
}
return returnList
}
fun checkResult(result: Result<Int>){
result.fold(onSuccess = { number ->
println("$number is even")
},onFailure = {
if (it is NumberNotEvenException){
println("${it.number} is Odd")
}
})
}
fun main() {
checkEvenNumbers((0..100).toList()).map {
checkResult(it)
}
}