Есть ли у Kotlin тип Result, такой как Swift? - PullRequest
1 голос
/ 05 июля 2019

Swift имеет тип Result, который объявлен так

enum Result<Success, Failure: Error> {
    case success(Success)
    case failure(Failure)
}

, который можно использовать так:

enum FooError: Error {
    case fizzReason
    case barReason
    case bazReason
}

func returnResult() -> Result<String, FooError> { 
    // ... Just imagine this method returns an error
}

switch returnResult() {
case .success(let string):
    print(s)
case .failure(.fizzReason):
    // do something
case .failure(.barReason):
    // do something
case .failure(.bazReason):
    // do something
}

Имеет ли Котлин аналогичный тип данных, который может бытьиспользуется таким же образом?

Ответы [ 2 ]

6 голосов
/ 05 июля 2019

Kotlin имеет Результат со свойствами, такими как isFailure и isSuccess , которые в основном эквивалентны Result of Swift.

Резюме

Result, тип в стандартной библиотеке Kotlin, который эффективно различный союз между успешным и неудачным результатом исполнения функции Котлина - Успех Т | Отказ броска, где успех T представляет успешный результат некоторого типа T и Failure Throwable представляет сбой с любым исключением Throwable. С целью эффективность, мы бы смоделировали его как общий встроенный класс стандартная библиотека.

ограничение

Результат не может использоваться в качестве прямого типа результата для функций Kotlin, свойства типа Result также ограничены: например,

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

Однако допускаются функции, которые используют тип Result в общих контейнерах или получают результат в качестве типа параметра:

fun findIntResults(): List<Result<Int>> // Ok
fun receiveIntResult(result: Result<Int>) // Ok

Использование (запущено онлайн) :

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)
        }
}
2 голосов
/ 05 июля 2019

Я не знаю, есть ли у Kotlin что-то подобное, но вот реализация, которая должна делать то же самое:

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

Фактический пример:

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