我最近开始学习Elixir,我非常享受它,但它是我用过的第一个函数式编程语言。我面临的问题来自我一直在阅读的教程,并且在LearnElixir上观看屏幕录像是您应该尽量避免使用IF
类型的陈述。如何在函数式编程语言中使用函数而不是早期返回
但我发现自己经常筑巢cond
或case
我会解决像Golang或JavaScript等语言这些解决方案通过只是使用if statment以早日回归,让超越该代码将无法运行,这阻止了我99%的时间必须通过检查falsy值并返回来嵌套条件。
因此,在Elixir
(或其他函数式编程语言)中,如何在不使用嵌套的情况下以适当的方式编写如下所示的内容,并利用语言的功能。
def loginPost(conn, %{"user" => user_params}) do
# Look for user in database
query = from u in User,
where: u.email == ^user_params["email"],
select: [u.email, u.username, u.password]
data = Repo.all(query)
# Check to see if a user had been found
case (length data) == 0 do
true -> # No user was found, send an error message
conn
|> json(%{ success: false, errors: ["Wrong username or password"]})
false -> # A user was found, compare password
[[email, username, db_password]] = data
case Comeonin.Bcrypt.checkpw(user_params["password"], db_password) do
true -> # Password was correct, set session and return a json response
conn
|> put_session(:authenticated, true)
|> put_session(:username, username)
|> put_session(:email, email)
|> json(%{success: true}) # Send json response and redirect on client side
false -> # Password was incorrect, send an error message
conn
|> json(%{success: false, errors: ["Wrong username or password"]})
end
end
end
end
我对如果应该避免的原因更加好奇......它根本没有意义。在任何语言中,分支都是程序的基石。在一个非平凡的程序中必然会出现某种分支。 – HuStmpHrrr
@HuStmpHrrr我在Elixir的IRC/Slack上讨论过的一些人通常会这样说,如果我太嵌套了,我想我在一个函数中做了太多的事情,并且会写另一个 – Datsik
这是别的东西。它适用于所有语言,即避免过多的嵌套结构。在fp中,没有循环结构,所以批评者都指向分支。我明白了这一点。它更多的是模块化。不仅仅是出于某种原因避免了某些特定的结构。如果使用if语句,我认为这段代码会更好。 – HuStmpHrrr