我试图比较Elixir中的字符串位 - 如果它们相等,那么if
块会触发,或者else
块应该触发。
def show(conn, %{"id" => id}) do
Logger.info id
Logger.info "----------"
Logger.info conn.assigns.current_user
if conn.assigns.current_user == id do
professional = Repo.get!(Professional, id)
render(conn, "show.html", professional: professional)
else
conn
|> put_flash(:error, "You must be logged in for that!")
|> redirect(to: site_path(conn, :index))
|> halt()
end
在上文中,Logger.info id
和Logger.info conn.assigns.current_user
都返回相同的内容,但永远不会输入if
块。
我做错了什么?
答案 0 :(得分:4)
我猜测你的id
是一个数字而IO.inspect(is_binary(conn.assigns.current_user))
是一个字符串。 {{1}}
答案 1 :(得分:2)
正如greg所说,你的para中的id很可能是一个字符串,所以你必须确保你正在比较相同类型的对象。 我会避免解析为整数,因为它会产生一些意想不到的结果,例如,如果你的id为nil。
我不是灵丹妙药的专家,但这里有一些我能想到的解决方案:
# String interpolation will automatically cast the interpolated values to string
if "#{conn.assigns.current_user}" == "#{id}" do
# Casting to char list can handle nil values as well as strings and integers
if to_char_list(conn.assigns.current_user) == to_char_list(id) do
# Regular to_string
if to_string(conn.assigns.current_user) == to_string(id) do
答案 2 :(得分:2)
多行if
在99%的案例中都是代码气味。您的代码段可能会被重写为:
case to_string(conn.assigns.current_user) do
id ->
render(conn, "show.html", professional: Repo.get!(Professional, id))
_ ->
conn
|> put_flash(:error, "You must be logged in for that!")
|> redirect(to: site_path(conn, :index))
|> halt()
end
我把这个作为答案只是为了表明方法,@ greg的答案仍然更好。
单行if
通常用作其他语言的三元组:
if a < 42, do: "tiny", else: "huge"