Elixirwith子句

示例

with子句用于组合匹配子句。看起来我们结合了匿名函数或具有多个主体(匹配子句)的句柄函数。考虑这种情况:我们创建一个用户,将其插入数据库,然后创建问候电子邮件,然后将其发送给用户。

如果没有该with子句,我们可能会这样写(我省略了函数实现):

case create_user(user_params) do
  {:ok, user} ->
    case Mailer.compose_email(user) do
      {:ok, email} ->
        Mailer.send_email(email)
      {:error, reason} ->
        handle_error
    end
  {:error, changeset} ->
    handle_error
end

在这里,我们使用case(可能是cond或if)处理业务流程的流程。这导致我们进入所谓的“厄运金字塔”,因为我们必须应对可能的条件并做出决定:是否进一步发展。用with语句重写此代码会更好:

with {:ok, user} <- create_user(user_params),
     {:ok, email} <- Mailer.compose_email(user) do
  {:ok, Mailer.send_email}
else
  {:error, _reason} ->
    handle_error
end

在上面的代码段中,我们使用重写了嵌套case子句with。在其中,with我们调用一些函数(匿名函数或命名函数),并在它们的输出上进行模式匹配。如果全部匹配,则with返回do阻止结果,else否则返回阻止结果。

我们可以省略,else因此with将返回do块结果或第一个失败结果。

因此,with语句的值是其do阻止结果。