Elixir中的return语句 [英] Return statement in Elixir
问题描述
我需要一个具有某种逐步逻辑的功能,我想知道如何制作一个.让我们以网站上的登录过程为例,因此我需要以下逻辑:
I need a function with some kind of a step-by-step logic and I wonder how I can make one. Let's take a log in process on a site as an example, so I need the following logic:
1)电子邮件存在吗?是->继续;否->返回错误
1) Email is present? Yes -> Go on; No -> Return an error
2)电子邮件至少包含5个字符?是->继续;否->返回错误
2) Email has at least 5 characters? Yes -> Go on; No -> Return an error
3)密码存在吗?是->继续;否-返回错误
3) Password is present? Yes -> Go on; No - Return an error
依此类推...
要实现此目的,我通常会使用return
语句,这样,如果不存在电子邮件,我会退出执行该函数,并使其返回错误.但是我在Elixir中找不到类似的东西,因此我需要一个建议.我现在看到的唯一方法是使用嵌套条件,但是也许有更好的方法?
And to implement this, I would usually use a return
statement so that if the email is not present, I quit executing the function and make it return an error. But I can't find something similar to this in Elixir so I need an advice. The only way I can see now is to use nested conditions but maybe there is a better way?
推荐答案
这是一个有趣的问题,因为您需要执行多项检查,提早退出,并在此过程中转换某些状态(连接).我通常会按照以下方式处理此问题:
This is an interesting problem because you need to perform multiple checks, exit early, and in the process transform some state (connection). I typically approach this problem as follows:
- 我将每个检查实现为一个功能,该功能将
state
作为输入并返回{:ok, new_state}
或{:error, reason}
. - 然后,我构建一个泛型函数,该函数将调用检查函数列表,如果所有检查都成功,则返回遇到的第一个
{:error, reason}
或{:ok, last_returned_state}
.
- I implement each check as a function which takes
state
as an input and returns{:ok, new_state}
or{:error, reason}
. - Then, I build a generic function that will invoke a list of check functions, and return either the first encountered
{:error, reason}
or{:ok, last_returned_state}
if all checks succeeded.
让我们首先看看通用函数:
Let's see the generic function first:
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
现在,我们可以按以下方式使用它:
Now, we can use it as follows:
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
或者将所有检查移至已命名的私有函数,然后执行以下操作:
Or alternatively move all checks to named private functions and then do:
perform_checks(conn, [
&check_mail_presence/1,
&check_mail_format/1,
...
])
您还可以研究 elixir-pipes ,这可能有助于您使用管道来表达这一点.
You could also look into the elixir-pipes which might help you express this with pipeline.
最后,在Phoenix/Plug的上下文中,您可以将检查声明为
Finally, in the context of Phoenix/Plug, you could declare your checks as a series of plugs and halt on first error.
这篇关于Elixir中的return语句的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!