我需要一个具有某种分步逻辑的函数,我想知道如何制作一个。我们以一个站点的登录过程为例,所以我需要如下逻辑:
1) Email is present? Yes -> Go on; No -> Return an error
2) Email has at least 5 characters? Yes -> Go on; No -> Return an error
3) Password is present? Yes -> Go on; No - Return an error
And so on ...
为了实现这一点,我通常会使用
return
声明,以便如果电子邮件不存在,我将退出执行该函数并使其返回错误。但是我在 Elixir 中找不到类似的东西,所以我需要一个建议。我现在能看到的唯一方法是使用嵌套条件,但也许有更好的方法?
最佳答案
这是一个有趣的问题,因为您需要执行多次检查、提前退出,并在此过程中转换某些状态(连接)。我通常按如下方式处理这个问题:
state
作为输入并返回 {:ok, new_state}
或 {:error, reason}
. {:error, reason}
或 {:ok, last_returned_state}
如果所有检查都成功。 让我们先看看泛型函数:
defp perform_checks(state, []), do: {:ok, state}
defp perform_checks(state, [check_fun | remaining_checks]) do
case check_fun.(state) do
{:ok, new_state} -> perform_checks(new_state, remaining_checks)
{:error, _} = error -> error
end
end
现在,我们可以按如下方式使用它:
perform_checks(conn, [
# validate mail presence
fn(conn) -> if (...), do: {:error, "Invalid mail"}, else: {:ok, new_conn} end,
# validate mail format
fn(conn) -> if (...), do: {:error, "Invalid mail"}, else: {:ok, new_conn} end,
...
])
|> case do
{:ok, state} -> do_something_with_state(...)
{:error, reason} -> do_something_with_error(...)
end
或者将所有检查移至命名的私有(private)函数,然后执行:
perform_checks(conn, [
&check_mail_presence/1,
&check_mail_format/1,
...
])
您也可以查看 elixir-pipes这可能会帮助您用管道表达这一点。
最后,在 Phoenix/Plug 的上下文中,您可以将您的检查声明为 a series of plugs and halt on first error .
关于elixir - Elixir 中的返回语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32239919/