Альтернатива 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, время: 22:47. |