Каква е разликата между параметрите, декларирани с var
, и тези, декларирани с out
? Как компилаторът ги третира по различен начин (напр. чрез генериране на различен код или чрез промяна на диагностиката, която издава)? Или различните модификатори просто позволяват на програмиста да документира предвиденото използване на параметрите? Какъв ефект имат типовете на параметрите върху въпроса?
Каква е разликата между var и out параметрите?
Отговори (3)
Параметър var
ще бъде предаден по референция и това е всичко.
Параметър out
също се предава по препратка, но се приема, че входната стойност е неуместна. За управлявани типове (низове, интерфейси и т.н.) компилаторът ще наложи това, като изчисти променливата преди началото на рутината, еквивалентно на писане на param := nil
. За неуправляеми типове компилаторът имплементира out
идентично с var
.
Имайте предвид, че изчистването на управляван параметър се извършва на сайта за повикване и така генерираният код за функцията не се променя с out
или var
параметри.
out
е важно за параметрите на интерфейса на външните функции, защото друг (не-Delphi) код може да го извика с боклук стойност. Но ако единствената разлика между var
и out
е в начина, по който компилаторът обработва извикващата страна, а извикващата страна не е в Delphi в сценария на Serg, тогава не разбирам каква разлика е Serg опитвайки се да изтъкна.
- person Rob Kennedy; 25.01.2013
out
параметрите са внедрени, толкова повече се чудя. Няма нужда да се нулира параметърът out
извън процедурата в родния Delphi код и не можах да разбера как текущата реализация на out
параметри може да помогне да се направи мост към други езици, които третират out
параметрите от интерфейсен тип по различен начин.
- person kludg; 25.01.2013
out
на var
, но оставите всичко останало същото, спира ли да работи?
- person Mason Wheeler; 26.01.2013
SHChangeNotification_Lock
е грешно. Това е както е описано в доклада за контрол на качеството. Промяната на out
на var
за декларацията в този отговор не променя нищо. Можете да погледнете генерирания код и да видите, че е идентичен. Не знам защо прие собствения си отговор там, защото е много грешен, поне по отношение на SHChangeNotification_Lock
.
- person David Heffernan; 26.01.2013
Няма голяма разлика за компилатора. Вижте отговора на Мейсън за това.
Семантично има голяма разлика:
var
казва на програмиста, че рутината може да работи с текущата си стойност,out
казва на програмиста, че рутината ще игнорира/отхвърли текущата си стойност.
out
в Delphi работи по същия начин като out
в C#, където е незаконно да се чете параметърът, преди да е бил написан. Когато хората декларират out
параметри в Delphi, мисля, че обикновено така възнамеряват да ги третират. Използването на out
вместо var
служи за документиране на това намерение, дори ако компилаторът всъщност не го налага. Четенето на параметър out
преди запис в него е грешка и бъг, дори ако компилаторът не го маркира като грешка.
- person Rob Kennedy; 25.01.2013
out
, за да документирам намерението си. Но когато попадна на функция с изходящ параметър, трябва да отида и да проверя.
- person David Heffernan; 25.01.2013
out
, казва на програмиста, че няма смисъл да подготвя това, с което го захранвате. Рутина с параметър var
се нуждае от подготовка и/или разглеждане, а out
не. Моля, посъветвайте ме как да пренапиша отговора си, за да го разгледам по-ясно.
- person NGLN; 25.01.2013
out
параметрите вероятно е написана за Delphi.NET или друго, но не и за Delphi. Компилаторът на Delphi просто не може да имплементира out
параметри според документацията и повдига въпроси какво всъщност представляват out
параметрите и кога трябва да се използват.
- person kludg; 25.01.2013
Малко късно, но само за протокола, попаднах на случай, при който var или out направиха голяма разлика.
Работех върху SOAP уеб услуга, която експортира следния метод:
function GetUser( out User :TUser ) :TResult;
който се импортира в C# като еквивалент на
function GetUser( out Result :TResult) :TUser;
когато промених out на var, той се импортира правилно.
Предполагам, че програмата за извикване на SOAP на Delphi третира резултата от функцията като параметър out и че наличието на два параметъра out обърква SOAP рутинните процедури на Delphi. Не съм сигурен дали има заобиколно решение, което да ви позволи да използвате out параметри.
out
по начина C#. Незаконно е да се чете изходящ параметър, преди да е бил напълно инициализиран. И функцията няма право да се връща, освен ако не я е инициализирала напълно. И C# получава правилна семантика за връщане на функцията, което е друг мой бъг. - person David Heffernan   schedule 25.01.2013