我首先注意到一个带有感叹号/爆炸(!)的函数,同时浏览凤凰教程(在Incoming Events部分中)
def handle_in("new_msg", %{"body" => body}, socket) do
broadcast! socket, "new_msg", %{body: body}
{:noreply, socket}
end
尾随感叹号是什么意思?它有什么作用吗?我一直在寻找并试着看,但我不确定我是否使用了正确的术语。到目前为止,似乎只有作为约定的函数会在失败时引发错误,但它总是意味着它。
我看到它的唯一提及出现在"编程Elixir"戴夫托马斯:
Identifiers in Elixir are combinations of upper and lower case ASCII
characters, digits, and underscores. Function names may end with a
question mark or an exclamation point.
并在the documentation中提及:
Notice that when the file does not exist, the version with ! raises an
error. The version without ! is preferred when you want to handle
different outcomes using pattern matching...
这些都没有解释这是否是其他灵药师或炼金术士或其他任何使用的惯例。请帮忙。
答案 0 :(得分:21)
此:
如果你看一下源代码,请注意,当文件不存在时,版本用!提出一个 错误。没有版本!当你想要处理时,它是首选 使用模式匹配的不同结果...
会更清楚。函数名中的!
符号只是一个语法协议。如果您看到一个函数在其名称中包含!
符号,则表示可能存在具有相同名称但没有!
符号的函数。这两个函数都会做同样的事情,但它们会以不同的方式处理错误。
没有!
的函数只会向您返回错误。您需要知道一种错误并根据您的类型进行处理。查看broadcast/3
函数(variant没有!
):
def broadcast(server, topic, message) when is_atom(server),
do: call(server, :broadcast, [:none, topic, message])
它只是调用给定的服务器并返回其结果。 broadcast!/3
函数也会这样做,但是:它会在没有broadcast
的情况下调用!
函数,会检查其结果并提升BroadcastError
exception:
def broadcast!(server, topic, message) do
case broadcast(server, topic, message) do
:ok -> :ok
{:error, reason} -> raise BroadcastError, message: reason
end
end
答案 1 :(得分:15)
它只是一个命名惯例。请查看此答案 - What's the meaning of "!", "?", "_", and "." syntax in elixir
! - 如果函数遇到错误,将引发异常。
一个很好的例子是Enum.fetch!(它也有一个相同的Enum.fetch,它不会引发异常)。在给定的索引处绑定元素(从零开始)。如果给定位置超出集合的范围,则引发OutOfBoundsError。
答案 2 :(得分:2)
你基本上把它做对了马克 - 如果出现问题,这是一个惯例,就是说要提出错误。
此page上有关于文件访问的文档 (向下滚动到短语 trailing bang )