我可以依赖def do ... after ... end语法吗?

时间:2016-02-13 06:39:57

标签: elixir

似乎函数定义可以像after语句一样具有try子句:

# after.exs
defmodule M do
  def f do
    IO.puts "hello"
    raise "die"
    IO.puts "world"
  after
    IO.puts "bye"
  end
end

iex(1)> M.f
hello
bye
** (RuntimeError) die
    after.exs:3: M.f/0
    (elixir) lib/code.ex:363: Code.require_file/2

虽然Kernel.def/2Kernel.SpecialForms.try/1Getting started - Named functions中没有记录这一点。

这是支持的功能吗?我可以依靠这个吗?

1 个答案:

答案 0 :(得分:2)

这似乎只记录在this place中。我不确定你是否理解它的目的,但正如该页面所说,这是省略try行的捷径:

  

有时你可能想要在try结构中包装函数的整个主体,通常是为了保证之后会执行一些代码。在这种情况下,Elixir允许您省略try行:

iex> defmodule RunAfter do
...>   def without_even_trying do
...>     raise "oops"
...>   after
...>     IO.puts "cleaning up!"
...>   end
...> end
iex> RunAfter.without_even_trying
cleaning up!
** (RuntimeError) oops

我个人从来没有使用过它,除了上面的例子,我还记得在任何代码中都看不到它。除了关于try try documentation的文档之外,我在文档中也找不到任何关于它的内容。我通常使用after字的唯一方法是使用receive do

iex> receive do
...>   {:hello, msg}  -> msg
...> after
...>   1_000 -> "nothing after 1s"
...> end
"nothing after 1s"

我相信这是Erlang的映射,所以你可能想问一下Erlang中的知识分子。但是,我发现Erlang邮件列表中的这封邮件很有意思:

Joe Armstrong about try-catch-after