传递/未传递参数时的处理情况和nil

时间:2017-01-02 03:50:20

标签: elixir

在我的Phoenix / Elixir应用程序中,我有这个:

def new(conn, %{"var1" => var1}) do
  # ......

当URL中没有传递参数“var1”或者它为nil时,它会引发异常。我该如何解决这个问题?问题是我想要处理3个案例:它没有被传递,它被传递但是nil或没有值&var1="并且当它正常传递时带有值。

2 个答案:

答案 0 :(得分:1)

无论您是要处理三种不同的情况,都应该处理三种不同的情况。有人可能会在函数子句中使用模式匹配来做到这一点:

def new(conn, %{"var1" => nil}) do
  IO.puts "nil passed"
end
def new(conn, %{"var1" => var1}) do
  IO.puts "var1 passed: #{inspect(var1)}"
end
def new(conn, %{} = _params) do
  IO.puts "var1 NOT passed"
end

请注意,条款的顺序很重要,因为模式匹配是按自然顺序从上到下完成的,因为函数声明会出现。

另一种方法是接收params并检查它是否包含var1

def new(conn, %{} = params) do
  if Map.has_key?(params, "var1") do
    %{"var1" => var1} = params
    IO.puts "var1 passed: #{inspect(var1)}"
  else
    IO.puts "var1 omitted"
  end
end

旁注:如果<{1}} 已通过 {{1},原始代码不会抛出异常}。

答案 1 :(得分:0)

我最近遇到了同样的问题。如果只有var1作为键,则上述版本有效,只要你有多个键就会变得棘手。

我通过使用默认值规范化哈希来修复。

@default_params %{"var1" => nil}

def new(conn, params) do
  params |> normalize |> handle
end

defp normalize(params) do
 @default_params |> Map.merge(params)
end
defp handle(%{"var1" => var1}) do
  IO.puts "var1 passed: #{inspect(var1)}"
end
defp handle(%{"var1" => nil}) do
  IO.puts "var1 NOT passed"
end