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)
        }
}