我在 Arrow 文档中看到过这个示例:
import arrow.resilience.Schedule
suspend fun main() {
var result = ""
Schedule
.doWhile<String> { input, output -> input.length <= 5 }
.repeat {
result += "a"
result
}
println(result)
}
output
我不明白 lambda中的的用途是什么,doWhile
因为它总是与 相同input
。
我个人认为 Arrow API 有时使用起来有点别扭。这只是一个例子,因为在这个特定情况下
input
,和output
总是相同且是多余的。解释
A
Schedule
有两个类型参数,一个Input
类型和一个Output
类型。它基本上由一个表示 的函数组成,ScheduleStep
该函数接受Input
并将其映射到Decision<Input, Output>
。Output
特定于计划步骤的类型(决策),而Input
必须与 lambda 的返回值的类型匹配repeat
(在您的情况下为字符串)。ScheduleStep
您可以创建多个s的链,其中的内容Input
将始终相同,并且只会Output
根据具体步骤进行更改。稍后可以使用
repeat
字符串调用但每次重复延迟一秒的 Schedule 可能如下所示:String类型
Input
必须在此处明确设置,但Output
是 Long,由spaced
函数定义。它仅计算其调用频率。如果您想添加一个条件来停止重复,就像您在问题中所做的那样
doWhile
,您只需将其附加即可:在
doWhile
lambda 中,参数的类型input
为 String,但output
现在参数的类型为 Long,因为这是Output
返回的 Schedule 的类型spaced
。您可以使用output
来基于它作为谓词(此处input.length <= 5
),例如,如果您想在五次迭代后停止:input
这就是为什么 lambda 中有两个不同的和参数的原因output
。注意:与问题中的示例相反,这里的两个参数是不同的。顺便说一句,
Output
ofdoWhile
总是与传入的相同,在这种情况下与spaced
返回的 Long 相同。现在,回到你问题的例子。你
doWhile
直接在Schedule 的伴随对象上使用,而不是在 Schedule 的实例上使用(如上面的示例所示):没有先前的 Schedule 也没有先前的
Output
类型,因此,底层发生的事情是首先创建一个身份Input
ScheduleStep,将 映射到自身,因此得名。Output
不仅与的类型Input
相同,实际值也始终相同。这就是为什么上述 lambda中的参数input
和是相同的,使用哪一个作为条件的基础并不重要。output
doWhile
doWhile
请记住,只有当您调用Schedule 的伴随对象时才会出现这种情况(就像您在问题中所做的那样),而不是像我的第一个示例那样在 Schedule 的实例上调用它。我发现设计一个提供冗余参数的 API 令人困惑,但也许理由是该doWhile
函数应该具有相同的签名,而与实际调用方式无关。我不知道,但事实就是这样。