停止管道操作器中的链条

问题描述 投票:0回答:5

我有这样的功能

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
5个回答
2
投票

你可以像这样在 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

0
投票

用一个简单的案例代替:

case check_file(url) do
  {:ok, file} ->
    IO.puts "ok"
    foo(file)
  {:error, _} ->
    IO.puts "KO, debug and stop!"
end

0
投票

可能最简单的方法是添加对

{:error, _}
模式的支持以发挥作用
foo
:

  def foo({:ok,_}) do
     IO.puts "do the stuff";
  end
  def foo({:error,_}), do: {:error, []}

但是在这种解决方案中,您需要从

{:error}
返回
test


0
投票

其他答案中没有提到的是,您可以在

test
函数中引发一些特定错误,然后在管道中包含的任何代码中捕获它。只有这样你才能真正停止任何任意长的管道。

但我不会这么做。我宁愿以不需要通过引发错误来停止管道的方式编写程序。


0
投票

在提出这个问题后,我已经意识到这一点了。但是,也许我可以提供我的 2 美分,这样如果其他人正在寻找这个问题的替代方案,就可以有另一个观点。

提出错误确实可以解决问题。如果您不太热衷于筹集/救援,那么您可以尝试:

return_value =
  case check_file(url) |> test() do
    {:ok, valid_value} -> foo(relevant_value)
    {:error, value_after_test} -> value_after_test
  end

为了实现这一点,需要您的函数返回值可用于进一步的管道或作为最终返回值,就像人们在 phoenix 中使用套接字实例所做的那样。 使其更易于阅读和遵循的方法是创建可以传递到管道中的结构,并在其中设置/“更改”其值

© www.soinside.com 2019 - 2024. All rights reserved.