Какова точка возврата в Ruby?
В чем разница между return
и просто помещением переменной, например:
возврат не возвращается
def write_code(number_of_errors)
if number_of_errors > 1
mood = "Ask me later"
else
mood = "No Problem"
end
mood
end
возвращение
def write_code(number_of_errors)
if number_of_errors > 1
mood = "Ask me later"
else
mood = puts "No Problem"
end
return mood
end
Ответы
Ответ 1
return
позволяет вам пробиваться рано:
def write_code(number_of_errors)
return "No problem" if number_of_errors == 0
badness = compute_badness(number_of_errors)
"WHAT?! Badness = #{badness}."
end
Если number_of_errors == 0
, то "No problem"
будет возвращено немедленно. Однако в конце метода это не нужно, как вы заметили.
Изменить: Чтобы продемонстрировать, что return
выходит немедленно, рассмотрите эту функцию:
def last_name(name)
return nil unless name
name.split(/\s+/)[-1]
end
Если вы вызываете эту функцию как last_name("Antal S-Z")
, она вернет "S-Z"
. Если вы называете его last_name(nil)
, он возвращает nil
. Если return
не прерывается немедленно, он попытается выполнить nil.split(/\s+/)[-1]
, что вызовет ошибку.
Ответ 2
Использование "return" не требуется, если это последняя строка, которая должна быть выполнена в методе, так как Ruby автоматически возвращает последнее вычисленное выражение.
Вам даже не нужно это окончательное "настроение", и вам не нужны эти назначения в инструкции IF.
def write_code(number_of_errors)
if number_of_errors > 1
"ERROR"
else
"No Problem"
end
end
puts write_code(10)
Выход:
ОШИБКА
Ответ 3
Я использую return, когда я просматриваю список, и я хочу выйти из функции, если любой член списка соответствует критериям. Я мог бы выполнить это с помощью одного утверждения, например:
list.select{|k| k.meets_criteria}.length == 0
в некоторых ситуациях, но
list.each{|k| return false if k.meets_criteria}
- тоже одна строка - на мой взгляд, добавлена гибкость. Например, в первом примере предполагается, что это единственная строка в методе и что мы хотим вернуться с этого момента независимо от того, что. Но если это тест, чтобы убедиться, что безопасно продолжать работу с остальным методом, первый пример должен будет обрабатывать это по-другому.
EDIT:
Чтобы добавить некоторую гибкость, рассмотрите следующую строку кода:
list_of_method_names_as_symbols.each{|k| list_of_objects.each{|j| return k if j.send(k)}}
Я уверен, что это может быть достигнуто в одной строке, без return
, но с верхней части моей головы я не вижу, как это сделать.
Но теперь это довольно гибкая строка кода, которая может быть вызвана любым списком логических методов и списком объектов, реализующих эти методы.
EDIT
Следует отметить, что я предполагаю, что эта строка находится внутри метода, а не блока.
Но это в основном стилистический выбор, я думаю, что в большинстве ситуаций вы можете и, возможно, избегать использования return
.
Ответ 4
Ruby всегда возвращается! лучший способ -
def write_code(number_of_errors)
(number_of_errors > 1)? "ERROR" : "No Problem"
end
это означает, что если number_of_errors > 1, он вернет ERROR else No Problem
Ответ 5
Хороший рубин дает эту хорошую возможность не указывать оператор return явно, но я просто чувствую, что в качестве стандартного программирования всегда нужно стремиться указывать "возвращаемые" утверждения везде, где это необходимо. Это помогает сделать код более читаемым для тех, кто приходит из разных источников, таких как С++, Java, PHP и т.д., И изучает рубин. Операция "return" ничего не навредит, поэтому зачем пропускать обычный и более стандартный способ возврата из функций.
Ответ 6
Одно маленькое предупреждение для тех, кто приходит с других языков. Допустим, у вас есть функция, подобная OP, и вы используете правило "последняя вещь вычисляется" для автоматической установки возвращаемого значения:
def write_code(number_of_errors)
if number_of_errors > 1
mood = "Ask me later"
else
mood = "No Problem"
end
end
и допустим, вы добавили оператор отладки (или записи в журнал):
def write_code(number_of_errors)
if number_of_errors > 1
mood = "Ask me later"
else
mood = "No Problem"
end
puts "### mood = #{mood}"
end
Теперь угадай, что. Вы нарушили свой код, потому что puts
возвращает nil, который теперь становится возвращаемым значением из функции.
Решение состоит в том, чтобы привыкнуть всегда явно указывать возвращаемое значение в последней строке, как это делал OP:
def write_code(number_of_errors)
if number_of_errors > 1
mood = "Ask me later"
else
mood = "No Problem"
end
puts "### mood = #{mood}"
mood
end
Ответ 7
Unnecesarity return
в последней строке в функции - это просто синтаксический сахар Ruby. В большинстве процедурных языков вам нужно написать return
в каждой (не-void в С++) функции.