Альтернатива return с меткой
Чтобы выйти из цикла можно использовать break
for(){
break;
}
В функции можно использовать return без выражения справа.
function func(){
return;
}
Чтобы во вложенном цикле выйти из внешнего можно использовать break с меткой
firstfor:
for(){
for(){
break firstfor;
}
}
Вопрос как из вложенной функции завершить внешнюю
function func1(){
functiob func2(){
//Что-то завершающие func1
}
}
|
function func1(){
try{
function func2(){
//Что-то завершающие
throw 'exit';
}
продолжение func1;
}catch(e){if e!=='exit' throw e}
}
Но оно гораздо медленее ретурнов. Легче сделать ретурн с опред значением и его на выходе проверять. try catch vs. returns кто быстрее ? |
Спасибо
Поставил + |
Цитата:
|
Цитата:
|
хорошо, а можно практический пример?
|
Цитата:
function getElement() {
[1, 2, 3].forEach(function (element) {
if (element % 2 == 0) {
// возврат в функционал - .forEach,
// но не выход из getElement
alert('found: ' + element); // found: 2
return element;
}
});
return null;
}
alert(getElement()); // null, а не 2
|
ну так здесь нету никакого завершения внешней функции из вложенной.
|
Dmitry A. Soshnikov,
че-та я тоже пример не понял. Цитата:
|
Цитата:
Цитата:
Вот этот раздел: http://en.wikipedia.org/wiki/Closure...in_sema ntics (там пониже как раз примеры на Ruby с разными вариациями return-a приводится) Но речь идёт только о возможном завершении стека вызова (когда контексты существуют); и в Ruby можно сделать ошибку return-a, когда он не сможет определить, в какой контекст возвращать. |
а можно увидеть, как эта функция на Ruby выглядела бы?
|
Цитата:
# ruby
def foo
f = Proc.new { return "return from foo from inside proc" }
f.call # control leaves foo here
return "return from foo"
end
def bar
f = lambda { return "return from lambda" }
f.call # control does not leave bar here
return "return from bar"
end
puts foo # prints "return from foo from inside proc"
puts bar # prints "return from bar"
Замыкания, порождаемые Proc.new - при return-e могут завершать контекст, в котором были порождены. Замыкания, порождаемые функцией lambda - не могут. Касаемо массива, метода .each и фунарга - я проверил, в версии 1.8.6 - и lambda, почему-то, завершает порождаемый контекст. В версии 1.9.1. это исправлено:
def test1
fn = lambda {|x| return x}
[1, 2, 3].each(&fn) # процедура передаётся с амперсандом
return nil
end
def test2
fn = Proc.new {|x| return x}
[1, 2, 3].each &fn # скобки вызова - опциональны
return nil
end
puts test1 # 1 - в 1.8.6, nil (правильно) - в 1.9.1
puts test2 # 1 - правильно
Есть ещё третий способ создать замыкание в Ruby - это блок кода (который можно преобразовать в процедуру). Различные методы (типа .each) как раз и используются с этими блоками кода.
def test3
[1, 2, 3].each {|x| return x} # сразу описываем блок кода
nil # слово return - тоже опциональное
end
puts test3 # 1 - при использовании блока, тоже выход из порождающего контекста
|
интересно... По поводу js я бы сделал так (поиск первого элемента, удовлетворяющего условию)
function getElement() {
return [1, 2, 3].findFirst(function( element ) {
return element % 2 == 0;
});
}
alert(getElement());
т.е. как минимум отсутствие такой функциональности не создает никаких сложностей. Кроме того, я бы даже сказал, что наличие таких возможностей усложняет код: глядя на return так сразу и не скажешь, что он завершает. Хотя это уже, конечно, "предварительное" мнение - надо попробовать эту штуку в действии Как я понял, return в замыкании, созданном с помощью Proc.new завершает функцию, в которой было создано замыкание. И использовать его, за пределами этой функции смысла не имеет может еще какие-нибудь примеры использования Proc.new есть? Т.е. на данный момент я вижу, что это можно использовать для поиска первого элемента Цитата:
|
Цитата:
С другой стороны, последний драфт стандарта по Ruby появился недавно (я не в курсе, вышла ли уже первая официальная версия), возможно, там что-то изменят, а пока все доки по руби - это исходники и доки на официальном сайте. Когда появится стандарт, можно будет однозначно говорить, как должно быть. Цитата:
fn = Proc.new {|x| return x}
fn.call 10 # ошибка
fn1 = Proc.new {|x| x}
fn1.call 10 # 10
def foo
fn = Proc.new do |x| # альтернативная запись блока {...} == do...end
return x
end
fn.call 10
return 'сюда не дошли'
end
foo # 10
Есть ещё несколько случаев, когда return из Proc.new завершится с ошибкой (когда контекст уже мёртв, когда вызывается в другом треде, др.) Вообще, можно выделить даже не 3, а целых 7 способов создать замыкания в Ruby (но они будут сводиться к 3-ём; остальные 4 - вариации/комбинации предыдущих). Цитата:
Я рассказываю, как есть (не привязываясь к ES, либо к другой технологии) - на твою фразу, что "не надо этого хотеть". Иногда это удобно, но в ES такой возможности нет. Нравится тебе это или нет, хочешь ли ты от этого отгородиться или нет, решил ли ты для себя, что это нужно/не нужно: это есть (в некоторых языках) и разработано с конкретной целью ;) |
Цитата:
|
Цитата:
|
Цитата:
|
Ну, здесь я уже не смогу помочь. Я рассказал и объяснил, как есть: что с этим делать тебе и как тебе к этому относиться - решать только тебе ;)
А то, что есть такой механизм и, что он существует независимо от того, понимаешь ли/принимаешь ли ты его, и что фраза в данном случае "не надо этого хотеть" - неверна - это истина. Цитата:
|
Цитата:
Цитата:
|
Цитата:
Кстати, однозначные призывы "есть суп ложкой" тоже можно нарушать с целью экспериментов от устоявшихся паттернов (ну, естественно, для этого должны быть обоснованные мотивации). А дальше ты принял позицию, выдающую это за какую-то ненужную вещь, и я должен тебе доказывать, почему это не так. Но, ведь, цель нашей беседы не в этом, правда? ;) Я просто тебя информировал, без определения, плохая это вещь или нет. Здесь ты сам уже примешь решение. Цитата:
Там есть ещё различия. Например, Proc.new (в отличие от lambda) не проверяет точное количество параметров (что также может быть удобно в определённых случаях). Если интересно - вот исходник на Ruby (выполненный даже больше в виде статьи) о замыканиях - http://innig.net/software/ruby/closures-in-ruby.rb - достаточно подробно описаны различные случаи (можешь сохранить, читать в редакторе с подсветкой, скрипт полностью рабочий и запускаемый). |
| Часовой пояс GMT +3, время: 07:19. |