2015-12-18 9 views
3

Dlang описывает выход параметр, как:Является ли параметр out значением ref, значение которого неявно повторно инициализируется?

параметра инициализируется при входе функции со значением по умолчанию для его типа.

После того, как параметр инициализирован значением по умолчанию для ввода функции, разве это не просто ref?

import std.stdio; 

void foo(out int x) 
{ 
    writeln(x); //prints 0 
    x = 2; 
} 

void main() 
{ 
    int x = 1; 
    writeln(x); //prints 1 
    foo(x); 
    writeln(x); //prints 2 
} 

Я не вижу никакой документации по сравнению с outref.
ли с точностью до концептуализации в out параметр в качестве ярлыка из письма:

import std.stdio; 

void foo(ref int x) 
{ 
    x = x.init; //happens implicitly 
    writeln(x); //prints 0 
    x = 2; 
} 

void main() 
{ 
    int x = 1; 
    writeln(x); //prints 1 
    foo(x); 
    writeln(x); //prints 2 
} 

Я не знаю тонкостей языка, поэтому я волнуюсь, что имея такое впечатление будет вызывать у меня будущее горе в непредвиденное обстоятельства.

Может ли быть проведено более сильное различие между этими parameter storage classes, или это действительно параметр ref, который автоматически переинициализируется?

ответ

2

Да, это все, что есть в реализации сегодня, но это не совсем то, что означает семантически.

Подумайте о параметрах out как дополнительных возвращаемых значениях, а не как аргументах в традиционном смысле, и вы должны быть в порядке. Функция не может принимать адрес своего возвращаемого значения и не может получать данные через него. Параметр out также не должен использоваться этими способами.


D не использовался ref. Вместо этого он использовал in, out и inout в качестве классов хранения параметров.

in означает (а значит, он все еще есть), что вы собираетесь смотреть, но не изменить или сохранить ссылку на него (последнее, что делает его отличным от const - вы имеете право хранить const, но не in или scope params, что позволяет теоретическому компилятору оптимизировать выделение памяти).Это просто для потребления данных.

out означает, что функция собирается хранить данные в этой переменной, но не собирается ее просматривать или хранить. Значения, которые уже находятся там заранее, будут потеряны, так как функция записывает в нее результат. Компилятор сбрасывает его при вводе функции, чтобы гарантировать, что программа не зависит от какого-либо значения, прошедшего через нее.

И, наконец, старый inout должен был взять данные и сохранить значение. Сегодня (ну, как и пять лет назад) это использование давно прошло, и inout означает нечто совершенно другое (const, но возвращающая константа условна на входе, константы const/неизменяемые/изменяемые) имеют то же самое, что и они) и прежнее использование было заменено на ref, что также расширило значение: оно больше не происходит ввода и вывода данных, а полномасштабная ссылка на другую переменную, что означает, что вам разрешено делать такие вещи, как принимать адрес.

В то время как out реализован как ref плюс автоматическая повторная инициализация, вы должны помнить исходное значение: вы записываете данные, но ничего не делаете. Не принимайте его адрес - это законно с ref (если это не scope ref или in ref ...), но неверно с out. Вы должны написать ему, не более того.

+0

«Представьте, что параметры являются дополнительными возвращаемыми значениями»: это правильно, но я бы сказал, что параметры не используются в идиоматическом коде D2. Использование Tuple!() В качестве возвращаемого значения часто является лучшим решением. – jpf

+0

meh, мне не нравится Tuple (я предпочитаю возвращать именованную структуру с именованными полями, если я иду по этому маршруту), но да, вы правы, много кода делает это, а параметры params относительно редки. –

2

Есть параметр out, значение которого неявно переинициализировано?

Да.

После того, как параметр инициализирован значением по умолчанию для ввода функции, не является ли это по существу просто ссылкой?

Да.

Может ли быть проведено более сильное различие между этими классами хранения параметров или это действительно параметр ref, который автоматически повторно инициализируется?

Последний. По крайней мере, я так думаю. Надеюсь, я ничего не пропущу.

+0

Это правда, но я думаю, что в этой истории больше. Позвольте мне опубликовать мою запись об этом в качестве ответа. –