Я только начал работу с новой командой нового места. Они сказали мне, что мы возвращаем ref вместо ценности в наших perl-модулях. Также я увидел что-то вроде return +{foo=>'bar'}; and return {foo=>'bar'};
В чем разница? И нужно ли возвращать ref или значение?Разница между возвратом + {} или {} в perl от функции и возвратом ref или значением
ответ
+
совершенно бесполезен.
Во-первых, некоторый фон.
Язык Perl имеет двусмысленности. Возьмем, к примеру
sub f {
{ } # Is this a hash constructor or a block?
}
{ }
действует синтаксис для блока («голое петля»).
{ }
является допустимым синтаксисом для хэш-конструктора.
И оба разрешены как заявление!
Поэтому Perl должен угадать. Perl обычно догадывается правильно, но не всегда. Вы можете дать ему «подсказки». Unary-+
можно использовать для этого. Unary-+
- полностью прозрачный оператор; он ничего не делает. Однако за ним должно следовать выражение (а не утверждение). { }
имеет только одно возможное значение как выражение.
Аналогичным образом вы можете обмануть Perl, чтобы угадать в другую сторону.
{; } # Perl looks head, and sees that this must be a block.
Вот пример, в котором Perl угадает неверно:
map { {} } 1..5 # ok. Creates 5 hashes and returns references to them.
map {}, 1..5 # XXX Perl guesses you were using "map BLOCK LIST".
map +{}, 1..5 # ok. Perl parses this as "map EXPR, LIST".
Что касается кода в вопросе, return
должно сопровождаться выражением (если что-нибудь), так что есть только один возможный интерпретация для return { ... };
, поэтому +
здесь совершенно бесполезен.
Большинство людей только устраняют необходимость при необходимости. Другие могут добавить +
всякий раз, когда это неоднозначно (даже если Perl догадается правильно). Но это он в первый раз, когда я слышал об использовании +
перед каждым конструктором хэшей.
Очень приятное объяснение, которое устраняет двусмысленность от двусмысленности. – stevieb
Обратите внимание, что поскольку 'map {}, 1..5;' имеет только одну действительную интерпретацию, поэтому Perl мог бы понять, что вы имели в виду, а не гадать. 1) Предполагается, что никто не делает никаких синтаксических ошибок, и 2) Когда вы устраняете двусмысленность, вы не только устраняете ошибку для Perl, но и для читателя. Короче говоря, лучше всего знать значение токенов как можно скорее. – ikegami
В чем разница?
Все те же, что и +
посторонние. Вы можете увидеть это с помощью B::Deparse:
$ perl -MO=Deparse -e'sub foo { return { foo => "bar" } }'
sub foo {
return {'foo', 'bar'};
}
-e syntax OK
$ perl -MO=Deparse -e'sub foo { return +{ foo => "bar" } }'
sub foo {
return {'foo', 'bar'};
}
-e syntax OK
В обеих случаях вы возвращаете ссылку на хэш.
Как Хантер Макмиллена сказал в комментариях, есть некоторые случаи, когда вам нужно использовать унарный оператор +
для разрешения неоднозначности.
Например, чтобы различать анонимный хэш и блок в map
:
$ perl -e'@a = map { $_ => "foo" }, 1..3' # { ... } treated as a block
syntax error at -e line 1, near "},"
Execution of -e aborted due to compilation errors.
$ perl -e'@a = map +{ $_ => "foo" }, 1..3' # { ... } treated as a hashref
И нужно ли возвращать реф или значение?
К «возвращает значение,» Я предполагаю, что ваши коллеги означают что-то вроде этого:
sub foo {
my %bar = (baz => 'qux');
return %bar; # as opposed to \%bar
}
my %hash = foo();
Подпрограммы могут только возвращать список скаляров, так что это примерно эквивалентно
my %hash = ('baz', 'qux');
Если %bar
содержит много элементов, копирование этого списка становится дорогим, поэтому лучше вернуть ссылку:
sub foo {
my %bar = (baz => 'qux');
return \%bar;
}
my $hashref = foo();
Примечание: Deparse является хорошей ссылкой, но это не является окончательным. Если вы хотите получить окончательное сравнение, вы можете использовать 'diff -u <(perl -MO = Concise, -exec, foo -e'sub foo {return {foo =>" bar "}} '2> & 1) <(perl -MO = Concise, -exec, foo -e'sub foo {return + {foo => "bar"}} '2> & 1) '. – ikegami
- 1. Разница между возвратом («abcd») и возвратом «abcd»?
- 2. Разница между возвратом переменной и возвратом значения вычисления
- 3. Есть ли разница между возвратом нового типа и возвратом объекта?
- 4. Разница между возвратом обещания и возвратом неопределенного внутри обещания
- 5. В чем разница между возвратом; и вернуть undef; в Perl
- 6. В чем разница между возвратом функции и возвратом в рекурсивной функции?
- 7. В чем разница между «печатью» и «возвратом»?
- 8. В чем разница между вызовом функции и возвратом функции?
- 9. Любая разница между явным и неявным возвратом в функции javascript?
- 10. Разница между возвратом * this по ссылке и значением
- 11. Разница между вызовом и возвратом рекурсивной функции в C++
- 12. Разница между эхом и возвратом в php?
- 13. Разница между console.log и возвратом в javascript?
- 14. В чем разница между выходом и возвратом?
- 15. Spring MVC Controller: в чем разница между «возвратом вперед», «возвратом перенаправления» и «возвратом файла jsp»
- 16. Любопытный Разница в производительности между возвратом значения или возвратом через действие <T> параметр
- 17. В чем разница между возвратом указателя на calloced int и возвратом адреса инициализированного int в функции?
- 18. В чем разница между возвратом функции и возвратом объекта в режиме просмотра Durandal?
- 19. В чем разница между возвратом действия и возвратом всей функции в Object Object?
- 20. Разница между возвратом родительского типа или дочернего типа
- 21. Обещание - разница между возвратом отклонения или отклонения (значение)
- 22. В чем разница между несколькими списками аргументов и возвратом функции?
- 23. В чем разница между вызовом и возвратом функции?
- 24. разница между возвратом отложенным. и возврат отложенных.();
- 25. Разница между новостями() и возвратом каретки ("\ r")
- 26. Разница между возвратом файла и FileStream от AWS до iOS
- 27. Есть ли разница между частичным приложением и возвратом функции?
- 28. Разница между возвратом ModelAndView в ajax-вызове
- 29. В чем разница между возвратом объекта ответа и эхо-выходом?
- 30. В чем разница между печатью и возвратом в python?
Используется иногда для устранения неоднозначности между ссылкой HASH и выражением BLOCK. Вы можете прочитать больше об этом в разделе '' perldoc perlref' '(http://perldoc.perl.org/perlref.html) –
О, дорогой. Perl, написанные программистами, не являющимися Perl! Неужели вам не нужно писать 'return \ 1'? Но всегда возвращать хеширование или массивные ссылки - это рецепт утечек памяти. – Borodin
«return ref вместо ценности» ... Я это видел. Обычно это означает, что возвращаемое значение всегда будет * ссылкой (будь то хэш, массив и т. Д.), Даже если оно пустое. Поэтому, если все хорошо, вы можете получить заполненную хеш-ссылку, но при неудаче или успехе, но ничего не сделано, пустой ref '{}' (хэш-код в этом случае). Затем вызывающий может: 'if (! Exists $ return -> {expected}) {do_something(); ...} ' – stevieb