问题 在Elixir中返回值?


我最近决定学习Elixir。来自C ++ / Java / JavaScript背景,我在掌握基础知识方面遇到了很多麻烦。这可能听起来很愚蠢但是如何在Elixir中返回语句?我环顾四周,似乎它只是一个功能的最后一行,即

def Hello do 
  "Hello World!"
end

这个函数会返回“Hello World!”,还有另一种方法可以返回吗?另外,你怎么早点回来?在JavaScript中,我们可以编写类似这样的内容来查找数组中是否有某个值:

function foo(a){
   for(var i = 0;i<a.length;i++){
      if(a[i] == "22"){
         return true;
      }
   }
   return false;
}

如何在Elixir中工作?


12988
2018-05-25 19:17


起源

这是另一个关于如何早退的例子: elixir-examples.github.io/examples/return-early - Brandon
@Brandon,谢谢man,所以在那个例子中如果“some_condition”为false,它会输出“do_something()”输出的值吗? - joe-tom
这根本不是一个愚蠢的问题。当一个函数用于命令式语言时,很难习惯每个函数返回计算的最后一个值的概念。坚持下去 - 一旦你习惯了每个函数返回一个值的想法,你就会发现你的函数会变得更有凝聚力。 - Onorio Catenacci
@wateriswet这是正确的,它将返回do_something()的值 - Brandon
可能重复 Elixir的退货声明 - Dennis


答案:


Elixir没有'break out'关键字,相当于其他语言中的'return'关键字。

通常,您要做的是重新构造代码,以便执行的最后一个语句是返回值。

以下是elixir中用于执行代码测试的惯用方法,假设您将'a'表示为行为类似于初始示例中的数组:

def is_there_a_22(a) do
  Enum.any?(a, fn(item) -> item == "22" end.)
end

这里真正发生的是我们正在重新思考一下我们的想法。如果我们找到我们正在寻找的东西,我们将搜索数组并提前返回,而不是程序方法,我们将在代码片段中询问您的真实情况: “这个阵列有22个吗?”

然后我们将使用elixir Enum库为我们运行数组,并提供 any? 功能测试,告诉我们是否符合我们关心的标准。

虽然这是一个可以通过枚举轻松解决的案例,但我认为您的问题的核心可能更多地适用于诸如程序方法中使用的“保镖模式”之类的事情。例如,如果我在方法中满足某些条件,请立即返回。一个很好的例子就是一个方法,如果你要做的事情是null,则返回false:

function is_my_property_true(obj) {
  if (obj == null) {
    return false;
  }
  // .....lots of code....
  return some_result_from_obj;
}

在elixir中真正实现这一目标的唯一方法是将警卫放在前面,并将一个方法分解出来:

def test_property_val_from_obj(obj) do
  # ...a bunch of code about to get the property
  # want and see if it is true
end

def is_my_property_true(obj) do
   case obj do
     nil -> false
     _ -> test_property_value_from_obj(obj)
   end
end

tl; dr - 没有相应的 - 你需要相应地构建你的代码。另一方面,这往往会使你的方法变小 - 你的意图也很明确。


8
2018-05-25 20:15





你是对的,因为总是返回最后一个表达式。甚至更多 - 语言中没有语句 - 只是表达式。每个构造都有一个值 - ifcase等等也没有提前退货。这似乎有限,但你很快就习惯了。

使用Elixir解决示例的常用方法是使用更高阶函数:

def foo(list) do
  Enum.any?(list, fn x -> x == "22" end)
end

4
2018-05-25 20:13



感谢您的解释,我必须围绕Elixir无言以对。 - joe-tom