2016-05-25 4 views
6

Я недавно решил изучить Эликсир. Исходя из фона C++/Java/JavaScript, у меня возникли проблемы с пониманием основ. Это может показаться глупым, но как бы вернуть утверждения в Elixir? Я посмотрел вокруг и, кажется, как будто это только последняя строка функции, т.е.Возвращаемые значения в 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; 
} 

Как бы, что работа в эликсира?

+1

Вот еще один пример того, как вернуться раньше: http: //elixir-examples.github.io/examples/return-early – Brandon

+0

@Brandon, спасибо, человек, поэтому в этом примере, если «some_condition» false, он выведет значение, которое «do_something()» выводит? –

+0

Это не глупый вопрос. Очень трудно привыкнуть к понятию каждой функции, возвращающей последнее значение, вычисленное, когда оно используется для императивных языков. Придерживайтесь этого - как только вы привыкнете к идее каждой функции, возвращающей значение, вы обнаружите, что ваши функции станут намного более сплоченными. –

ответ

5

Эликсир не имеет «вспыхнуть» ключевое слово, которое было бы эквивалентно «возврата» ключевого слова на других языках ,

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

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

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

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

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

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

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

+0

Это имеет большой смысл, спасибо, что объяснил это так подробно –

4

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

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

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

Спасибо за объяснение, что я должен окутать голову в высказывание Эликсира. –

Смежные вопросы