Elixir 相当于 while true

Elixir equivalent to while true

我想在Elixir

中重写这个方法(在Python这里写的)
def something()
    while True:
        x = function()
        y = function()
        if x != y:
            return x
    

function()生成一个随机值,所以执行迟早会结束。

我的问题是以最“实用的方式”翻译 while True

我想出了这个解决方案,但我认为可读性不是很好。


def something() do
    internal(function(), function())
end

defp internal(a, a) do
    internal(function(), function())
end

defp internal(a, _) do
    a
end

有更好的方法吗?

PS:function()必须在每个循环中始终调用两次,并且不能重写。

谢谢

递归是你的朋友

  def something do
    x = function()
    y = function()
    if x != y, do: x, else: something()
  end

Elixir 也有变量和 if 表达式,所以你真正需要做的就是用递归调用替换 while True

  def something() do
    x = function()
    y = function()

    if x != y do
      x
    else
      something()
    end
  end

我认为你的解决方案还不错,只是习惯于看到多个函数子句在起作用。您可以 re-arrange 使其更具可读性,但这只是个人喜好。

def something(), do: something(nil, nil)
defp something(x, x), do: something(function(), function())
defp something(x, _y), do: x

(x, x) 子句将在参数相等时执行。

(x, _y) 子句,仅 returns x,否则执行。

但我不得不承认 potibas 的回答非常简单,可能是一个很好的折衷方案。我想我更喜欢函数子句方式 一般 因为它使参数明确并且隐藏得更少 side-effects.

为了多样性,这里不递归回答,基于Stream.iterate/2 and Stream.take_while/2. Note, that any infinite stream generator might be used instead of iterate/2, e. g. Stream.cycle/1

0
|> Stream.iterate(&(&1 + 1))
|> Stream.map(fn _ -> {f1(), f2()} end)
|> Stream.take_while(fn {x, y} -> x != y end)
|> Enum.to_list()

在很多情况下,这种解决方案更可靠。