我有这样的功能
check_file(url) |>test |> foo
检查文件返回
{:ok,_} or {:error,_}
我有两个用于模式匹配的函数
def test({:ok,_}) do
IO.puts "ok";
end
def test({:error,_}) do
IO.puts "KO, debug and stop!";
end
如果我得到:错误,我不想调用我的最后一个函数(foo),但我想在调试中显示错误
我可以这样做吗?
你可以像这样在 Elixir 中使用 with 语句
with {:ok, file} <- check_file(url) do
file |> foo |> foo
else
IO.puts "KO, debug and stop!"
end
如果
test
也返回一个
{:ok, something}
元组,这尤其有用。然后就可以展开 with
如果您的
check_file(url)
方法只可能在开始时出现错误,您可以采用如下简单的解决方案:
def test({:ok,file}) do
IO.puts "ok";
do_your_stuff_with_the_file()t |> foo
end
def test({:error,_}) do
IO.puts "KO, debug and stop!";
end
用一个简单的案例代替:
case check_file(url) do
{:ok, file} ->
IO.puts "ok"
foo(file)
{:error, _} ->
IO.puts "KO, debug and stop!"
end
可能最简单的方法是添加对
{:error, _}
模式的支持以发挥作用 foo
:
def foo({:ok,_}) do
IO.puts "do the stuff";
end
def foo({:error,_}), do: {:error, []}
但是在这种解决方案中,您需要从
{:error}
返回 test
。
其他答案中没有提到的是,您可以在
test
函数中引发一些特定错误,然后在管道中包含的任何代码中捕获它。只有这样你才能真正停止任何任意长的管道。
但我不会这么做。我宁愿以不需要通过引发错误来停止管道的方式编写程序。
在提出这个问题后,我已经意识到这一点了。但是,也许我可以提供我的 2 美分,这样如果其他人正在寻找这个问题的替代方案,就可以有另一个观点。
提出错误确实可以解决问题。如果您不太热衷于筹集/救援,那么您可以尝试:
return_value =
case check_file(url) |> test() do
{:ok, valid_value} -> foo(relevant_value)
{:error, value_after_test} -> value_after_test
end
为了实现这一点,需要您的函数返回值可用于进一步的管道或作为最终返回值,就像人们在 phoenix 中使用套接字实例所做的那样。 使其更易于阅读和遵循的方法是创建可以传递到管道中的结构,并在其中设置/“更改”其值