了解带有多个子句的 Elixir 函数

M.N*_*Nar 1 elixir pattern-matching

我最近开始学习 Elixir。来自面向对象的编程背景,我无法理解 Elixir 函数。

我正在关注 Dave Thomas 的书Programming Elixir >= 1.6,但我不太明白函数是如何工作的。

在书中,他举了以下例子:

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"?))   ?# this file exists?
-> "Read data: IO.puts \"Hello, World!\"\n"

 handle_open.(File.open(?"??nonexistent"?))           ?# this one doesn't?
 -> Error: no such file or directory"
Run Code Online (Sandbox Code Playgroud)

我不明白参数是如何工作的。是否有隐含的 if, else 语句隐藏在某处?

She*_*yar 5

这里有几件事情正在发生,我会尽量涵盖所有这些事情。首先,这里使用了两个不同的函数。一个是命名函数 ( File.open) ,另一个是您创建的匿名函数,分配给变量handle_open两者的调用方式略有不同

当您在File.open函数内部调用该函数handle_open时,基本上意味着您正在调用handle_open其结果。但是File.open/2函数本身可以返回两个值:

  1. {:ok, file} 如果文件存在
  2. {:error, reason} 如果没有(或者如果有另一个错误)

handle_open函数使用模式匹配多个函数子句来检查响应是什么并返回适当的消息。如果给定值“匹配指定的模式”,则执行该语句,否则检查下一个模式。虽然从某种意义上说,类似于一个if-else语句,但更好的类比是case关键字:

result = File.open("/some/path")

case result do
  {:ok, file} ->
    "The file exists"

  {:error, reason} ->
    "There was an error"
end
Run Code Online (Sandbox Code Playgroud)