Возврат значений в 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?

2 ответов


Elixir не имеет ключевого слова "break out", которое было бы эквивалентно ключевому слову "return" на других языках.

обычно вы бы перестроили свой код, чтобы последний выполненный оператор был возвращаемым значением.

Ниже приведен идиоматический способ в elixir выполнить эквивалент вашего теста кода, предполагая, что вы имели в виду " a " как нечто, что ведет себя как массив, как в вашем первоначальном примере:

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

на самом деле здесь происходит то, что мы немного перестроить наше мышление. Вместо процедурного подхода, когда мы будем искать по массиву и возвращаться раньше, если мы найдем то, что искали, мы собираемся спросить, что вы действительно ищете в фрагменте кода: - У этого массива есть где-нибудь 22?"

затем мы собираемся использовать библиотеку перечислений elixir для запуска массива для нас и предоставить any? функция с тестом, который скажет нам, если что-нибудь соответствует критериям, которые мы заботились о.

хотя это случай, который легко решается с помощью перечисления, я думаю, что, возможно, сердце вашего вопроса больше относится к таким вещам, как "шаблон вышибалы", используемый в процедурных методах. Например, если я удовлетворяю определенным критериям в методе, сразу возвращайтесь. Хорошим примером этого может быть метод, который возвращает false, если то, над чем вы собираетесь работать, равно null:

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

единственный способ действительно сделать это в эликсире-поставить охрану фронт и фактор из метода:

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 - нет эквивалента-вам нужно соответствующим образом структурировать свой код. С другой стороны, это имеет тенденцию держать ваши методы небольшими - и ваши намерения ясными.


вы правы в том, что последнее выражение всегда возвращается. Более того-в языке нет утверждений - только выражения. Каждая конструкция имеет значение -if, case, etc. Также нет раннего возвращения. Это может показаться ограничивающим, но вы быстро привыкаете к этому.

обычный способ решить ваш пример с эликсиром - использовать функцию более высокого порядка:

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