我正在探索Elixir,并且对此表示怀疑。假设我有这样的代码:
defmodule Drop2 do
def fall_velocity(planemo, distance) do
gravity = case planemo do
:earth -> 9.8
:moon -> 1.6
:mars -> 3.71
end
:math.sqrt(2 * gravity * distance)
end
end
Run Code Online (Sandbox Code Playgroud)
我传递一个负数distance以使函数失败:
iex(8)> Drop2.fall_velocity(:earth, -20)
** (ArithmeticError) bad argument in arithmetic expression
(stdlib) :math.sqrt(-392.0)
drop2.ex:9: Drop2.fall_velocity/2
Run Code Online (Sandbox Code Playgroud)
通过添加异常处理,可以使此方法更好:
defmodule Drop2 do
def fall_velocity(planemo, distance) do
try do
gravity = case planemo do
:earth -> 9.8
:moon -> 1.6
:mars -> 3.71
end
:math.sqrt(2 * gravity * distance)
rescue
ArithmeticError -> {:error, "Distance must be non-negative number"}
CaseClauseError -> {:error, "Unknown planemo: #{planemo}"}
end
end
end
Run Code Online (Sandbox Code Playgroud)
现在我们有:
iex(9)> Drop2.fall_velocity(:earth, -20)
{:error, "Distance must be non-negative number"}
Run Code Online (Sandbox Code Playgroud)
太好了,但是我看不到模式如何ArithmeticError匹配。在前面的示例中,生成的异常主要是文本,并(ArithmeticError)用括号括起来。这不是Elixir中通常的模式匹配。这是怎么回事?
在前面的示例中,生成的异常主要是文本,并在括号中包裹了(ArithmeticError)。
异常不是文本,而是正在iex打印异常的文本表示形式,而不是确切的值(source)。确切的例外是:
iex(1)> try do
...(1)> :math.sqrt(-1)
...(1)> rescue
...(1)> e -> e
...(1)> end
%ArithmeticError{message: "bad argument in arithmetic expression"}
Run Code Online (Sandbox Code Playgroud)
这是一个ArithmeticError带有message字段的结构,如Kernel.SpecialForms.try / 1的文档所述:
救援条款
除了依赖模式匹配外,抢救子句还为异常提供了一些便利,使人们可以通过其名称抢救异常。
| 归档时间: |
|
| 查看次数: |
362 次 |
| 最近记录: |