如何优雅地检查Erlang的许多条件? [英] How do I elegantly check many conditions in Erlang?

查看:192
本文介绍了如何优雅地检查Erlang的许多条件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以当用户发送注册帐号的请求时,他们会发送用户名,密码,电子邮件等信息。注册功能必须验证其所有数据。一个例子是:

So when a user sends a request to register an account, they send their username, password, email, and other info. The registration function must verify all of their data. An example would be:


  • 验证电子邮件不使用

  • 验证用户名不使用

  • 验证用户名是字母数字

  • 确认所有字段都超过X个字符长

  • 确认所有字段小于Y字符长

  • verify email not in use
  • verify username not in use
  • verify username is alphanumeric
  • verify all fields are above X characters long
  • verify all fields are less than Y characters long

现在我不想有一个5级深的if或case语句,但还有什么其他选项?将它分割成单独的函数听起来好像是一个好主意,但是我只需要以某种有条件的方式检查函数的返回值,并回到原来的问题。

Now I don't want to have a 5 level deep if or case statement, but what other options do I have? Splitting it into separate functions sounds like a good idea, but then I just have to check the return value of the functions in some sort of conditional and it's back to the original problem.

我可以将它们分成多个函数,然后调用一个if语句,其中所有的条件都是OR'd在一起,但这不会给我我想要的,因为我需要如果有一个可以告诉用户具体的错误。

I could separate them into functions and then call an if statement with all of the conditionals OR'd together, but that wouldn't give me what I want because I need to be able to tell the user the specific error if there was one.

如何处理这种情况在erlang?是否有一个等效的return语句,或者它必须是函数中的最后一个可执行行作为返回值?

How does one handle this kind of situation in erlang? Is there an equivalent of a return statement, or does it have to be the last executable line in a function to be a return value?

推荐答案

Joe Armstrong的建议之一:程序成功案例代码与错误处理分离。你可以这样做

One of Joe Armstrong's suggestion: program success case code separated from error handling. You can make it in this way

create_user(Email, UserName, Password) ->
  try
    ok = new_email(Email),
    ok = valid_user_name(UserName),
    ok = new_user(UserName),
    ok = strong_password(Password),
    ...
    _create_user(Email, UserName, Password)
  catch
    error:{badmatch, email_in_use} -> do_something();
    error:{badmatch, invalid_user_name} -> do_something();
    error:{badmatch, user_exists} -> do_something();
    error:{badmatch, weak_password} -> do_something();
    ...
  end.

注意,你可以做所有的错误捕捉到更好的create_user函数。

note that you can do all errors catches out of create_user function which is better.

create_user(Email, UserName, Password) ->
    ok = new_email(Email),
    ok = valid_user_name(UserName),
    ok = new_user(UserName),
    ok = strong_password(Password),
    ...
    _create_user(Email, UserName, Password).

main() ->
  try
    ...
    some_function_where_create_user_is_called(),
    ...
  catch
    ...
    error:{badmatch, email_in_use} -> do_something();
    error:{badmatch, invalid_user_name} -> do_something();
    error:{badmatch, user_exists} -> do_something();
    error:{badmatch, weak_password} -> do_something();
    ...
  end.

模式匹配是Erlang中最酷的事情之一。请注意,您可以将代码引入badmatch错误

Pattern match is one of coolest things in Erlang. Note that you can involve your tag to badmatch error

{my_tag, ok} = {my_tag, my_call(X)}

和自定义数据

{my_tag, ok, X} = {my_tag, my_call(X), X}

如果异常足够快,你取决于你的期望。速度在我的2.2GHz Core2 Duo Intel:
在一秒钟内有大约2百万的异常(0.47us),而600万的成功(外部)函数调用(0.146us) - 可以猜测该异常处理大约为0.32us。
在本机代码中,每秒6.8和47百万,处理可能需要0.125us。对于try-catch构造可能会有一些额外的成本,这是本机和字节码中成功函数调用的5-10%。

If exception is fast enough for you depends of your expectations. Speed on my 2.2GHz Core2 Duo Intel: about 2 millions exceptions in one second (0.47us) compared to 6 millions success (external) function calls (0.146us) - one can guess that exception handling takes about 0.32us. In native code it is 6.8 vs 47 millions per second and handling can take about 0.125us. There can be some additional cost for try-catch construct which is about 5-10% to success function call in both native and byte-code.

这篇关于如何优雅地检查Erlang的许多条件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆