Elixir能否像其他语言闭包捕获块外变量?如何统计retry模块重试次数?
问题解答
闭包变量捕获疑问说明
Elixir 中的变量都是不可变的,无法像支持可变变量的语言那样在闭包内部修改外部作用域的变量。你示例中 retry_while 代码块内的 count = count + 1 只是创建了一个和外部同名的局部新变量,每次循环都会基于外部的初始值 0 计算,永远只能得到 1,因此无法实现累计计数的效果。
正确实现方式
retry_while 原生支持迭代间传递自定义状态,我们可以直接把调用次数作为状态在每次迭代中传递即可,不需要依赖外部变量,修改后的代码如下:
defmodule Test do use Retry import Stream def call_service(count) do IO.puts "call_service #{count}" %{"errors" => true} end def hello do # 将初始调用次数 0 作为 retry_while 的初始状态 retry_while 0, with: linear_backoff(500, 1) |> take(5) do count -> new_count = count + 1 call_service(new_count) |> case do %{"errors" => true} -> {:cont, new_count} result -> {:halt, result} end end end end
上述代码中,每次迭代结束后我们通过 {:cont, new_count} 将最新的计数传递给下一次迭代,就能在 call_service 中拿到正确的累计调用次数。
内容的提问来源于stack exchange,提问作者Hongseok Yoon
相关产品推荐
相关产品推荐

