Это не является законным для параметров scope
, чтобы избежать функции. Предполагается, что компилятор гарантирует, что никакие ссылки на эти данные не выйдут из функции. Он используется в основном с делегатами, поскольку он позволяет компилятору избежать выделения закрытия, поскольку он знает, что делегат не убежит.
const ref
является const
- так же, как in
бы - но переменная передается по ссылке, вместо того, чтобы быть скопированы, так вы избежите копию. Однако в отличие от C++const ref
не Работа с rvalues. Это должно быть дано lvalue. Итак, если вы объявляете параметр const ref
, это будет ограничивать то, что вы можете передать ему. Обычно вам нужно объявить переменную, чтобы перейти к ней, тогда как in
примет временное.
void func(const ref int var) {}
int a;
func(a); //legal
func(7); //illegal
Оба этих звонков было бы законным, если func
принял const
или in
. Итак, в общем, вопрос заключается не в том, следует ли использовать const ref
или in
. Вопрос в том, следует ли использовать const
или in
. И в этом случае вопрос заключается в том, хотите ли вы использовать scope
или нет, поскольку оба они - const
. И вы используете scope
, если вы хотите, чтобы никакая ссылка на переменную, которую вы передаете, не удаляла эту функцию, поэтому она обычно используется только с делегатами, но может быть полезна с классами или массивами.
Однако функция pure
в функции гарантирует, что ссылки на какой-либо из ее аргументов не могут быть исключены, кроме как через возвращаемое значение (поскольку функции pure
могут использовать только глобальные переменные, если они являются неизменяемыми или являются типами значений и являются константами), поэтому pure
обычно дает вам все, что вам нужно для параметров, которые являются классами и массивами. Кроме того, если тип возврата является классом или массивом, вы вообще не хотите его делать, чтобы аргументы не могли убежать, потому что вместо того, чтобы повторно использовать что-либо из этих аргументов в возвращаемом значении, функция вынужден сделать копию, которая, как правило, менее эффективна.
Таким образом, scope
, как правило, используется только с делегатами, но порой полезен для классов или массивов. Как правило, предпочтительнее, чтобы функции были pure
в любом случае, так что это поможет решить большую часть проблемы. Таким образом, хотя не стоит использовать in
, часто бывает мало смысла использовать in
вместо const
. И вы обычно используете только const ref
, если вы действительно хотите избежать копирования передаваемой переменной, потому что в противном случае вы можете передавать только lvalues этой функции. You может перегрузить функцию таким образом, чтобы она имела версию, которая принимает const
, и тот, который принимает const ref
, но это, очевидно, приводит к дублированию кода, поэтому, если вы действительно не хотите const ref
, это, вероятно, просто лучше всего использовать const
.
EDIT:
scope
еще предстоит реализовать ни на что, кроме делегатов (по состоянию на 2013-06-18), так что использование либо scope
или in
с чем-либо, кроме делегатов опрометчивым. На данный момент они вводят в заблуждение, и если/один раз scope
реализован для чего угодно, кроме делегатов, существует высокий риск того, что ваш код сломается из-за ссылок на переменные, отмеченные scope
или in
экранированием.
1. хороший, это объясняет, почему я не смог воспроизвести эффект. 2. Итак, вы говорите, что если параметр функции имеет '' 'класс хранения, он копируется? Должен ли я использовать 'const ref' тогда? – Arlen
С текущим выбором компилятора, все на основе DMD, оно копируется. Но опрятная вещь в том, что она по-прежнему технически реализована, потому что пользователь не может сказать разницы. Для того, чтобы DMD воспользовался этим для оптимизации, он должен полностью реализовать «область» в первую очередь. Если вы определили копирование как узкое место и хотите оптимизировать, использование 'const ref' - хорошая идея. –
Как вы так много знаете о DMD? вы один из основных разработчиков? – Arlen