- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在考虑有关 suspend
的事情Arrow 的文档详细解释了:suspend () -> A
提供与 IO<A>
相同的保证.
因此,根据文档,只需使用 suspend
我们正在将不纯函数转换为纯函数:
不纯
fun log(message: String): Unit = println(message)
fun main(): Unit {
log("Hey!")
}
纯净
suspend fun log(message: String): Unit = println(message)
fun main(): Unit = runBlocking {
log("Hey!")
}
事实上,只需添加 suspend
将函数变成纯函数令人惊讶,但clearly explained in the doc .
考虑到这一点,我的下一个疑问与可能导致错误 ( Throwable
) 或值 A
的业务服务建模有关。 .
到目前为止,我正在做这样的事情:
suspend fun log(message: String): Either<Throwable, Unit> = either { println(message) }
suspend fun add(sum1: Int, sum2: Int): Either<Throwable, Int> = either { sum1 + sum2 }
suspend fun main() {
val program = either<Throwable, Unit> {
val sum = add(1, 2).bind()
log("Result $sum").bind()
}
when(program) {
is Either.Left -> throw program.value
is Either.Right -> println("End")
}
}
但是,考虑到 suspend fun fn() : A
是纯的,相当于 IO<A>
,我们可以将上面的程序重写为:
suspend fun add(sum1: Int, sum2: Int): Int = sum1 + sum2
suspend fun log(message: String): Unit = println(message)
fun main() = runBlocking {
try {
val sum = add(1, 2)
log("Result $sum")
} catch( ex: Throwable) {
throw ex
}
}
有什么理由选择suspend fun fn(...): Either<Throwable, A>
过度暂停fun fn(...): A
?
最佳答案
如果您想与 Throwable
合作有 2 个选项,kotlin.Result
或arrow.core.Either
.
最大的区别是runCatching
之间和Either.catch
。哪里runCatching
将捕获所有异常,并且 Either.catch
只会捕获non-fatal exceptions 。所以Either.catch
会防止您意外吞咽kotlin.coroutines.CancellationException
.
您应该将上面的代码更改为以下内容,因为 either { }
没有捕获任何异常。
suspend fun log(message: String): Either<Throwable, Unit> =
Either.catch { println(message) }
suspend fun add(sum1: Int, sum2: Int): Either<Throwable, Int> =
Either.catch { sum1 + sum2 }
Is there any reason to prefer suspend fun fn(...): Either<Throwable, A> over suspend fun fn(...): A?
是的,使用 Result
的原因或Either
返回类型中的内容将强制调用者解决错误。强制用户解决错误,即使在 IO<A>
内也是如此或suspend
自 try/catch
以来仍然有值(value)最后是可选的。
但是使用 Either
跟踪整个业务领域的错误变得真正有意义。或者跨层但以类型化的方式解决它们。
例如:
data class User(...)
data class UserNotFound(val cause: Throwable?)
fun fetchUser(): Either<UserNotFound, User> = either {
val user = Either.catch { queryOrNull("SELECT ...") }
.mapLeft { UserNotFound(it) }
.bind()
ensureNotNull(user) { UserNotFound() }
}
关于kotlin - 是否有任何理由使用 suspend fun fn(...) : Either<Throwable, A> 而不是 suspend fun fn(...) : A?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72318777/
您好,我希望我的下一个输出(在本例中就是字母)在上一个输出之后输出 8 个空格。这适用于第一个字符,但之后的 printf 语句不起作用。它在第一个 printf 语句之后立即打印,我试图将其设置为
我想知道制作 std::list<>::splice 背后的基本原理是什么使引用被拼接到新容器中的子序列的迭代器无效。这对我来说有点不合逻辑,尤其是考虑到标准 std::container::swap
谁能告诉我为什么我应该使用 Azure Function 输出绑定(bind)(例如 SendGrid 或 Twilio)而不是仅仅在我的 C# 函数中显式使用适当的 SDK(例如 Sendgrid
我们在当前项目中使用 React 和 TypeScript,我遇到了以下行为。 import React, { Component } from 'react'; 我将上面的行替换为下面的行,因为它似
我是一名优秀的程序员,十分优秀!