elixir中的模式匹配返回值映射

时间:2016-11-30 22:16:01

标签: pattern-matching elixir

在工作中我遇到了一些看起来不太优雅的代码,编译器抱怨我们有未使用的变量。我想知道处理这种情况的惯用方法是什么。

defp parse_create_case_response({create_status, http_status, body}) do
    case {create_status, http_status} do
        {:ok, 201} ->
            %{"errors" => errors, "id" => id, "success" => success} = Poison.decode! body
        _other ->
            {:error, %{message: "Internal error", error_code: :internal_server_error}}
    end
end

编译器抱怨errorsiderror都未使用过。我明白为什么他们没用,但我想知道我应该如何处理这个问题。我应该在每个变量前放一个_来告诉编译器它们是否未被使用?或者完全做其他事情?

代码中还有其他问题会在代码审查中解决,我只是想知道如何帮助我的同事克服困难。

1 个答案:

答案 0 :(得分:3)

从它的外观来看,我假设你将这个函数二的结果与另一个函数中的变量相匹配。编译器告诉你它们没有被使用,应该是一个很好的提示,可能整个方法可能被重构。没有看到调用代码很难,但我可能会将匹配移动到调用函数并返回解析后的响应体。

这将使linter高兴:)

所以这个:

defp parse_create_case_response({create_status, http_status, body}) do
    case {create_status, http_status} do
        {:ok, 201} ->
            %{"errors" => errors, "id" => id, "success" => success} = Poison.decode! body
        _other ->
            {:error, %{message: "Internal error", error_code: :internal_server_error}}
    end
end

将具有与此相同的效果:

  defp parse_create_case_response({{:ok}, {201}, _body}) do
    Poison.decode! body
  end

  defp parse_create_case_response(_response) do
    {:error, %{message: "Internal error", error_code: :internal_server_error}}
  end

我们不需要在第二个问题上进行模式匹配的原因是因为如果它不匹配第一个函数头,那么我们真的不在乎结果是什么,因为我们知道我们有什么返回。

<强>无论其 如果您坚决要求返回地图,那么您可以将其更改为:

  defp parse_create_case_response({{:ok, {201}, body}) do
    body
    |> Poison.decode!
    |> generate_map
  end

  defp parse_create_case_response(_response) do
    {:error, %{message: "Internal error", error_code: :internal_server_error}}
  end


  defp generate_map(%{"errors" => errors, "id" => id, "success" => success}) do 
    %{"errors" => errors, "id" => id, "success" => success}
  end

这不是很漂亮,但它仍然非常清楚发生了什么。再一次不确切知道这种方法的背景是什么,很难做得更好。