【发布时间】:2018-09-20 03:08:18
【问题描述】:
有没有办法打断理解?
我正在考虑类似 Python 的 for-break-else。
例如,假设我正在遍历一个整数列表,当我从中生成一个新列表时,我想检查它是否不包含 0。
我可以这样做吗:
for x <- [1, 2, 0, 3] do
case x do
0 -> break
_ -> x
end
end
if broke do
:error
else
:ok
end
我想我想得太迫切了,正确的函数方法应该是这样的,带有递归和累加器:
def traverse_and_check(list, acc \\ []) do
case list do
[] -> {:ok, reverse(acc)}
[0 | _tail] -> :error
[x | tail] -> traverse_and_check(tail, [x | acc])
end
end
Elixir 有这样的控制流程吗?
【问题讨论】:
-
我能想到的唯一函数是
Enum.reduce_while但 IMO 它会不如你的递归解决方案那么优雅。不过,我会将case转换为traverse_and_check/2声明中的3 个子句。 -
@Dogbert 啊,你说得对,我对 Elixir 还是很陌生。我也发现递归方法更优雅,但来自 Python 世界,
for-else起初在我看来是优雅的方法......虽然它似乎违背了 Elixir 的哲学,即错误不是控制流(好吧,从技术上讲,break不是错误,但它是“例外情况”)。不过,感谢您指出Enum.reduce_while! -
我会说你试图让理解做一些它不应该做的事情。理解旨在处理传递给它的集合中的所有元素。如果你需要跳出一个坏元素,那么要么 a.) 在开始理解之前过滤掉任何可能的坏元素,要么 b.) 编写递归代码,这是处理循环的 FP 方式。
标签: elixir list-comprehension control-flow