Function 功能在长生不老药中是如何工作的?

Function 功能在长生不老药中是如何工作的?,function,arguments,elixir,Function,Arguments,Elixir,在《编程长生不老药》一书中,DaveThomas给出了一个例子 handle_open = fn {:ok, file} -> "Read data: #{IO.read(file, :line)}" {_, error} -> "Error: #{:file.format_error(error)}" end handle_open.(File.open("code/intro/hello.exs")) handle_open.(File.open("nonexisten

在《编程长生不老药》一书中,DaveThomas给出了一个例子

handle_open = fn
  {:ok, file} -> "Read data: #{IO.read(file, :line)}"
  {_, error} -> "Error: #{:file.format_error(error)}"
end

handle_open.(File.open("code/intro/hello.exs"))
handle_open.(File.open("nonexistent"))
我不明白为什么函数的第二次调用进入第二个流。 还有为什么我们不将参数传递到func中:

handle_open = fn(file)

这是一个多子句匿名函数
handle\u open
有两个子句,一个用于匹配模式为
{:ok,file}
的参数,另一个用于
{uu,error}
的参数。将执行与参数匹配的第一个模式。给出的代码几乎相当于[1]以下代码:

handle_open = fn arg ->
  case arg do
    {:ok, file} -> ...
    {_, error} -> ...
  end
end
因此,如果文件存在,
file.open
将返回
{:ok,file}
,并执行第一个子句。如果不匹配,将返回与第二个子句匹配并执行的
{:error,error}


[1] :“几乎”,因为在两种情况下,当没有任何模式匹配时引发的错误将略有不同

这实际上只是模仿了长生不老药的模式匹配行为

您也可以在模块函数上进行模式匹配

defmodule MyModule do
  def read_file(path) do
    File.open(path) |> handle_file()
  end

  defp handle_file({:ok, file}) do
    // File there..
  end

  defp handle_file({_, error}) do
    // Could not open file.. because of `error`
  end
end
就像书中的例子一样,我会尝试打开case子句中的文件,并将结果委托给适当的函数:

defmodule FileReader do

  def read_file(path) do
    case File.open(path) do
      {:ok, file} -> handle_file(file)
      {_, error} -> handle_error(error)
    end
  end

  defp handle_file(file) do
    // File there..
  end

  defp handle_error(error) do
    // 
  end
end