在if语句中分配变量和测试可能吗?

时间:2017-03-08 22:17:21

标签: elixir

请查看以下代码:

    current_user = Plug.Conn.get_session(conn, :current_user)
    unless current_user == nil do
      Logger.info "User #{current_user.id} logged out"
    end

这段代码有效,但我觉得它不像Elixir一样。来自C我习惯了这样的事情:

if ((current_user = get_session("current_user")) != NULL) {
  log("User %d logged out, current_user->id);
}

所以在同一行分配和测试。 Elixir有可能吗? 我到底做错了吗?谷歌搜索我觉得我应该总是避免在Elixir中的陈述,因为应该总是有一个更好 - 更多功能的方式。

2 个答案:

答案 0 :(得分:3)

是的,您可以在Elixir的同一行中分配和测试:

if current_user = Plug.Conn.get_session(conn, :current_user) do
  Logger.info "User #{current_user.id} logged out"
end

如果你需要if / else语句,在测试期间没有分配的另一种方式在Elixir中执行它将使用case

case Plug.Conn.get_session(conn, :current_user) do
  nil ->
    # Handle user is not present
  current_user ->
    # Handle user is present
end

(以上逻辑记录了当会话中存在current_user时用户已注销,这可能看起来令人困惑,但根据问题中的代码是预期的行为)

答案 1 :(得分:2)

有一条经验法则:如果您使用<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:opencv="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_smile" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="MyActivity"> <VideoView android:id="@+id/videoViewSmile" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="0.5" /> <RelativeLayout android:id="@+id/remaining_fifty_percent" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="0.5"> </RelativeLayout> </LinearLayout> ,则出现问题。有很多非常罕见的情况,if位于Elixir的正确位置。

正如@navinpeiris指出的那样,你可以在这里使用if,但我个人会选择Kernel.SpecialForms.with/1。一旦你习惯了它,它就是非常方便的构造:

case

首先,当前用户的值与with %User{} = current_user <- Plug.Conn.get_session(conn, :current_user) do Logger.info "User #{current_user.id} logged out" end struct匹配,使其比仅针对%User{}检查更安全。如果匹配成功,则执行nil中的do块。如果没有,则可选的with子句(在上面的示例中不存在。)

else中的条款可能与逗号结合使用。特殊表格有很好的文档(上面链接。)我最近也wrote a blog post