Заметки
Впечатления от Rio

:: Меню ::
:: На главную ::
:: FAQ ::
:: Заметки ::
:: Практика ::
:: Win API ::
:: Проекты ::
:: Скачать ::
:: Секреты ::
:: Ссылки ::

:: Сервис ::
:: Написать ::

:: MVP ::

:: RSS ::

Яндекс.Метрика


Язык Delphi продолжает развиваться, и в новой Delphi 10.3 мы получили возможность объявления переменных и констант по месту использования (Inline Variable Declarations) с областью видимости внутри содержащего их блока, на манер Си-подобных языков.

begin
   var i: Integer;
   i := 1;
   // или сразу с инициализацией
   var j: Integer := 2;
   const M: Integer = 3;
end;

При этом управляемые переменные автоматически очищаются при выходе из блока.

begin
   var Intf: IInterface;
   if GetInterface(IInterface, Intf) then // Intf.AddRef
      UseIntf(Intf);
end; // Intf.Release

Для переменных, тип которых не указан явно, добавлен автоматический вывод типа по значению инициализатора.

begin
   var x := 1;
   ShowMessage(x.ToString);
end;

Ну и вдогонку добавлена возможность объявления переменной в заголовке цикла for, что в совокупности с автоматическим выводом типа очень даже удобно.

begin
   for var i := 1 to 10 do
      ShowMessage(i.ToString);

   for var i := 'a' to 'z' do
      ShowMessage(i);
end;

Правда тут нужно помнить, что за пределами блока, содержащего переменную, обратиться к ней уже не получится (что вполне логично, но достаточно непривычно для дельфиста со стажем). Но выход из ситуации весьма прост.

begin
   var i: Integer;
   for i := 1 to 10 do
      ShowMessage(i.ToString);
   ShowMessage(i.ToString);
end;

Из ограничения области видимости переменной границами блока вытекает еще один интересный способ применения этого нововведения.

begin
   begin
      var x := 1;
   end;

   begin
      var x := 1.024;
   end;

   begin
      var x := '1';
   end;

   begin
      var x := '1.024';
   end;

   begin
      var x := Now;
   end;
end;

Конечно же, как и раньше, мы можем перекрывать глобальные переменные.

var
  x: Integer;

procedure TForm1.Button1Click(Sender: TObject);
begin
  x := 1;

  var x{: string} := '1'; // Char
  ShowMessage(x);
end;

Разбирая автоматический вывод типа переменных следует обратить внимание на следующий пример:

begin
   var s := 'a';
   s := s + 'bcd';
   ShowMessage(s);
end;

Он не скомпилируется:

[dcc32 Error] Unit1.pas(29): E2010 Incompatible types: 'Char' and 'string'

Это вполне логично, так как переменная s "получила" тип Char. При объявлении переменой без указания типа следует помнить следующее:

var x1 := '';             // string
var x2 := 'a';            // Char
var x3 := string('a');    // string
var x4 := 'aa';           // string
var x5 := AnsiString(''); // AnsiString
var x6 := AnsiChar('a');  // AnsiChar

так что последний блок нужно переписать так

begin
   var s: string := 'a';
   s := s + 'bcd';
   ShowMessage(s);
end;

или так

begin
   var s := 'ab';
   s := s + 'cd';
   ShowMessage(s);
end;

Развитие языка - процесс, безусловно, нужный и важный. Я не вижу ничего плохого в том, чтобы заимствовать из других языков какие-либо решения, и Inline Variable Declarations не является исключением. Конечно, к нему нужно немного привыкнуть, ведь дельфисту со стажем удобнее искать объявление переменных в одном, заранее известном, месте. А объявление переменных в for лично мне кажется удобным, и я бы с удовольствием этим воспользовался, но...

Я не буду спешить с переходом на Rio, и вот почему. Мое впечатление испорчено скинами, которые разработчики натянули на студию. И дело не только в визуальном восприятии (хотя я бы хотел иметь возможность отключать их, от слова совсем...). Скины периодически глючат, что весьма раздражает. Уже не раз сталкивался с ситуацией, когда скроллируя текст в окне редактора кода ползунок скроллбара стоит на месте как вкопанный. Это значительно затрудняет ориентацию в коде, особенно если он имеет большой объем. Да и вообще, неужели больше нечем заняться, кроме как наведением красоты?

Лучше заниматься дальнейшим развитием языка. На следующем этапе можно было бы добавить тернарный оператор:

var x := (a > b) ? c : d;

и сокращенные операторы

x += 2; // этот оператор мог бы работать и для строк
x -= 2;
x *= 2;
x /= 2;

Но не только для простых арифметических операций, но и такие (список далеко не полный, это всего лишь пример)

x %= 2;  // Mod
x \= 2;  // Div
x &= 2;  // And
x |= 2;  // Or
x ^= 2;  // Xor
x != 2;  // Not
x $= 2;  // Power
x >>= 2; // Shr
x <<= 2; // Shl

В конце концов, добавьте поддержку длинной арифметики и перезагрузку операторов для классов в VCL. Для начала этого бы вполне хватило.

При использовании материала - ссылка на сайт обязательна