我喜欢管道,Elixir 喜欢管道,但返回 {:ok, actual_return_value} 似乎也很常见。有没有用管道处理这个的习语?
我现在正在学习“Programming Elixir”,以下练习的解决方案可能是可能的,但不完整。
File.cwd()
|> IO.puts()
Run Code Online (Sandbox Code Playgroud)
我不是在寻找这个解决方案:
{:ok, ret} = File.cwd()
IO.puts(ret)
Run Code Online (Sandbox Code Playgroud)
没有惯用的方法来管理第二个 arg。
在两种情况下,elixir不鼓励使用管道:
每当有意义时,核心库都会尽最大努力提供所有的糖,使管道成为一种魅力。考虑调整字符串。我们有两个replace/4函数:并且具有几乎相似的功能,但前者将字符串作为第一个参数,以便在字符串出现时更容易地通过管道传输到链中,而后者接受正则表达式作为第一个参数。String.replace/4 Regex.replace/4
如果您发现自己对如何使用管道感到困惑——这是一个明确的信号,您不应该使用管道。就这么简单,语言本身暗示了最好的方法。事实上,没有人{:ok, value}从总是成功的函数中返回。也就是说,可能还有其他一些结果。在问题的情况下,{:error, reason}。让我猜猜:你不希望你的代码在上面爆炸。与灵药好心提醒你一下。当然,您仍然可以使用Kernel.elem/2,但是您真的想要吗?我打赌没有。
至少有两种不同的方法,具体取决于您实际想要实现的目标。
一种是使用 monadic SpecialForms.with/1,它要么继续执行子句,要么返回第一个不匹配的结果。
with {:ok, a} <- Mod.fun1(),
{:ok, b} <- Mod.fun2(a),
{:ok, c} <- Mod.fun3(b),
do: IO.puts(c)
Run Code Online (Sandbox Code Playgroud)
这样你要么输出c 要么返回第一个不匹配(读取:错误)的结果。
另一种解决方法是使用Kernel.SpecialForms.case/2.
File.cwd()
|> case do
{:ok, result} -> result
{:error, reason} -> LOG_OR_SOMETHING
end
Run Code Online (Sandbox Code Playgroud)
选择您的任何选择,但请记住:管道应该在它所属的地方使用,而不是无处不在。