kotlin swift_在Kotlin中重新创建swift结果类型

本文探讨了在Kotlin中模仿Swift的Result类型的过程。作者对比了Kotlin和Swift中Result类型的使用,发现Kotlin的Result类型在默认情况下无法作为函数返回值。为了改进这一点,作者创建了自己的Result类型版本,利用了Kotlin的sealed class特性,实现了更简洁、一致的错误处理。文章详细介绍了如何在Kotlin中定义和使用这个自定义的Result类型。

kotlin swift

In Swift, I use the Result type extensively. Mostly for async callbacks, but it’s generally a nice, tidy and consistent way to provide a value that can either be a success or failure as a result of calling a function.

在Swift中,我广泛使用Result类型。 通常用于异步回调,但这通常是一种不错的,整洁且一致的方式,以提供一个值,该值可以由于调用函数而成功或失败。

When I started learning Kotlin, I found that there is a Result type included (since Kotlin 1.3), but to my dismay you cannot (by default) use this class as a return value for a function.

当我开始学习Kotlin时,我发现其中包含一个Result类型( 自Kotlin 1.3起 ),但令我沮丧的是,您不能( 默认情况下 )将此类用作函数的返回值。

I have never been happy with Kotlin’s built-in version of the Result type, anyway. Having to check if isSuccess or isFailure, null-check if the success or failure value exists or use the fold function seems archaic and not really necessary in neither Kotlin or Swift thanks to their generics.

无论如何,我从未对Kotlin的Result类型的内置版本感到满意。 必须检查isSuccessisFailure ,对成功或失败值是否存在或使用fold函数进行空检查似乎是过时的,而且由于Kotlin或Swift的通用性,它们实际上并不是必需的。

So I set out to create my own version of Result in Kotlin, and to do that I used Kotlin’s closest equivalent to Swift’s powerful enums, a sealed class:

因此,我着手在Kotlin中创建自己的Result版本,并为此使用了Kotlin最接近的等效于Swift强大的枚举的sealed class

The use of generics here looks quite verbose (and a bit overwhelming), but it’s required, since the way sealed classes work is by creating subclasses of the sealed class. Here’s how you’d use this new Result type:

在这里泛型的使用看起来很冗长(有点让人不知所措),但这是必需的,因为密封类的工作方式是通过创建密封类的子类。 使用这种新的Result类型的方法如下:

fun doSomething(): Result<String, Error> {
    return Result.Success("Yay, it was successful!")
}


fun doSomethingElse(): Result<Int, Error> {
    return Result.Failure(Error.CouldntDoSomethingElse)
}

In the above code, we have two functions. One function that returns a Result with a Success type of String, and another function that returns a Result with a Success type of Int. Both functions return a Failure type of Error, which is just another sealed class that implements Throwable (since our Result’s Failure type requires a type that is Throwable):

在上面的代码中,我们有两个功能。 一个函数返回一个ResultSuccess类型的String ,另一个函数返回一个ResultSuccess型的Int 。 这两个函数都返回ErrorFailure类型,这是另一个实现Throwable sealed class (因为我们的ResultFailure类型需要一个Throwable类型):

sealed class Error : Throwable() {
object CouldntDoSomethingElse : Error()
}

Although the declaration for the Result class looks complicated with generics, we only need to explicitly define the Success and Failure type once when declaring the return type of each function.

尽管Result类的声明看起来很泛型,但在声明每个函数的返回类型时,我们只需要显式定义一次SuccessFailure类型。

When it comes to actually returning either Success or Failure, you can just pass the appropriate value and Kotlin handles the rest.

当涉及到实际返回SuccessFailure ,您可以传递适当的值,而Kotlin将处理其余的值。

为什么要使用密封类? (Why use sealed classes?)

Sealed classes are the closest match to Swift’s awesome and powerful enums. You can use an instance of a sealed class in a when statement like you would a switch statement in Swift, and if you’re using the result of the when statement, Kotlin will make sure you’ve either handled every branch (Swift calls these cases), or added a fallback else branch (like Swift’s default fallback):

密封类是最接近Swift强大且强大的枚举的类。 您可以像在Swift中使用switch语句一样在when语句中使用sealed class的实例,如果您使用的是when语句的结果,Kotlin将确保您处理了每个分支(Swift会调用这些case ),或添加了一个后备else分支(如Swift的default后备):

fun amazingFunction() {
    when (val result = doSomething()) {
        is Result.Success -> Log.d("TAG", "The result is successful! ${result.value}")
        is Result.Failure -> Log.e("TAG", "The result is not successful!", result.failure)
    }
}

And that’s all there is to it really. Here’s the default Kotlin equivalent for comparison:

这就是全部。 这是默认的Kotlin等效项供您比较:

fun doSomething(): Result<String> {
    return Result.success("Yay, it was successful!")
}


fun doSomethingElse(): Result<Int> {
    return Result.failure(Error.CouldntDoSomethingElse)
}


fun amazingFunction() {
    doSomething().fold(
        onSuccess = {
            Log.d("TAG", "The result is successful! $it")
        },
        onFailure = {
            Log.e("TAG", "The result is not successful!", it)
        })
}

That code actually won’t compile without jumping through some hoops because you can’t use Kotlin’s Result type as a return value anyway, but comparing it, I feel like my version of the Result type is cleaner and allows you to use a when statement, which is very common to see across a Kotlin codebase. If you needed fold for functional programming it would be trivial to add an extension onto my Result class:

该代码实际上不会跳过某些循环而不会编译,因为无论如何您都无法将Kotlin的Result类型用作返回值,但是与之相比,我觉得我的Result类型的版本更清晰,允许您使用when语句,这在整个Kotlin代码库中很常见。 如果您需要fold进行功能编程,那么在我的Result类上添加扩展将是微不足道的:

fun <S, F : Throwable> Result<S, F>.fold(onSuccess: (S) -> Unit, onFailure: (F) -> Unit) {
    when (this) {
        is Result.Success -> onSuccess(value)
        is Result.Failure -> onFailure(failure)
    }
}


fun amazingFunction() {
    doSomething().fold(
        onSuccess = {
            Log.d("TAG", "The result is successful! $it")
        },
        onFailure = {
            Log.e("TAG", "The result is not successful!", it)
        })
}

Another bonus of my Result type is you know what type the Throwable will be, because you’ve explicitly declared it in the return type. If you need it to be less restrictive/more generic like the built-in Result type (which doesn’t let you specify the type of Throwable at all), you can still just declare the Failure type as Throwable:

我的Result类型的另一个好处是您知道Throwable将是哪种类型,因为您已经在返回类型中明确声明了它。 如果您需要限制更少/更通用,例如内置的Result类型(根本不允许您指定Throwable的类型),则仍然可以将Failure类型声明为Throwable

fun doSomething(): Result<String, Throwable> {
return Result.Failure(IllegalStateException("Now I can use any Throwable here!"))
}

Enjoy!

请享用!

翻译自: https://medium.com/@KaneCheshire/recreating-swifts-result-type-in-kotlin-f0a065fa6af1

kotlin swift

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值