在 Kotlin 中使用带有返回“Result”的转换的“mapCatching”时如何避免嵌套“Result”对象?

问题描述 投票:0回答:1

我们正在使用 Kotlin 的

Result
类和
mapCatching
函数,该函数采用可能返回任意类型的转换函数。在我们的例子中,转换本身可能会失败,因此我们让它返回另一个
Result
对象。 (我们当然也可以在转换函数中抛出一个
Exception
,但为了保持一致性,我想在那里也使用
Result
是有意义的。如果没有,请让 use 知道。)

但是,当我们这样做时,我们最终会得到嵌套的

Result<Result<T>>
对象,这使得处理结果变得复杂。有没有办法避免这种嵌套并将结果展平为单个
Result<T>

当问ChatGPT时,答案是引入这样的扩展功能:

inline fun <T, R> Result<T>.flatMapCatching(transform: (T) -> Result<R>): Result<R> {
    return fold(
        onSuccess = { transform(it) },
        onFailure = { Result.failure(it) }
    )
}

这当然是有道理的 😄 但这让我想到了一个问题:为什么这不是 Kotlin 标准实现的一部分?有没有更干净的方法来处理嵌套的

Result<Result<T>>
对象?


旁注:我对 Kotlin 非常陌生,最近才加入这个团队,该团队目前正在从用 Rust 编写代码过渡,似乎有一个不同的

Result
实现。所以也许我们只是缺少正确的资源来得出一个好的结论。因此,如果这个问题已经得到解答,请引导我们找到该资源。到目前为止,我们例如读过 Roman Elizarov – Kotlin 和异常,但它并没有真正帮助我们。

kotlin chaining
1个回答
0
投票

mapCatching
旨在捕获 lambda 中引发的异常。也就是说,您在 lambda 中执行的操作不应该返回另一个
Result<T>
- 它应该只是抛出一个异常来表明它失败了。

如果您可以更改在

mapCatching
中调用的任何方法的签名,那么您应该这样做。将其更改为抛出异常而不是返回
Result<T>

否则,您可以使用

getOrThrow()
来抛出包含在
Result<T>
内的异常。

// suppose someOperation returns a Result<T> and you cannot change it to throw an exception instead.
someResult.mapCatching { someOperation().getOrThrow() }
© www.soinside.com 2019 - 2024. All rights reserved.