Несмотря на то, что TStringHelper появился давным давно (если мне не изменяет память, то ещё в Delphi XE3), с удивлением обнаруживаю, что не все понимают зачем этот record helper появился в Delphi? В основном, конечно, подобные вопросы звучат из уст тех, кто с Delphi знаком слабовато, скажем так, на уровне реализации программы решения квадратного уравнения. Однако, раз по такому запросу ко мне попадают в блог, то попробую дать на него максимально исчерпывающий ответ. Итак, разберемся зачем в Delphi нужен TStringHelper?
Немного истории
Помощники классов и записей (class helper и recode helper) появились в Delphi давно. По крайней мере я впервые использовал class helper для NativeXML в далеком 2010 году, кто-то говорит, что хэлперы известны ещё с Delphi 2005. В общем, кто бы и что не говорил, а хэлперам в Delphi минимум 9 лет. Помощники оказались достаточно полезным нововведением, позволяющим расширять функциональность классов, не прибегая к наследованию.
Так, например, сейчас разработчики Delphi 10.3 Rio расширили в Release 1 возможности библиотеки HTTP Client API для работы с GZip.
Возможности хэлперов от версии к версии Delphi претерпевали некоторые изменения и в Delphi XE3 появились record helper для нативных типов данных: TSingleHelper,TDoubleHelper, TExtendedHelper, TStringHelper и так далее.
Вот с этого самого места — с Delphi XE3 и появился извечный вопрос: зачем?
Вариант №1. Помощники для нативных типов данных Delphi — это удобно
Самый простой ответ — удобно. Кто-то может со мной не согласиться, но этот ответ имеет полное право на существование. Банальнейший пример: как определить длину строки? Те кто «родом» из Delphi 7 и более ранних версий быстро ответит, например так:
Length(Str)
или, как вариант, так для ShortString:
var S: string[10] Len: integer; begin S:='абвгд'; Len:=Ord(S[0]); end;
Однако, если вы человек в Delphi новый, то придется копаться в Code Insight в поисках нужной функции или перерывать хэлп по Delphi. Однако с TStringHelper всё становиться намного проще. Пишем:
var S: string; begin S:='абвгд' S. //тут сработает Code Insight и выдаст все методы помощника end;
Сразу после того как мы ставим точку после имени переменной (S) мы получаем весь набор методов работы со строками. Как видите, для новичка это более простой способ погрузиться в Delphi.
Аналогичным образом можно комбинировать различные методы работы помощников для различных типов данных. Например:
var S: string; begin S:='абвгд '; ShowMessage(S.TrimRight.Length.ToString); end;
Здесь используются возможности сразу двух помощников:
- TStringHelper — для того, чтобы удалить пробел справа (TrimRight) и получить длину строки (Length)
- TIntegerHelper — для перевода значения длины строки (Integer) в строку (ToString)
В общем получилось достаточно удобно и понятно. Но это не единственная причина появления TStringHelper в Delphi.
Вариант №2. Развитие Delphi в части поддержки мобильных платформ
И это можно считать основной, самой веской и важной причиной появления TStringHelper в Delphi. Дело в том, что «родные» строки в Delphi являлись всегда 1-основными (1-based), то есть первый символ строки в Delphi равен единице. Например, если вы попробуете скомпилировать вот такой код для Win32:
procedure TForm6.Button1Click(Sender: TObject); var S: string; begin S:='абвгд '; ShowMessage(S[0]); end;
То получите ошибку (проверено в Delphi 10.3 Rio Release 1):
[dcc32 Error] E2157 Element 0 inaccessible - use 'Length' or 'SetLength'
Однако во многих языках программирования, в том числе и в тех, которые используются в разработке для мобильных платформ строки являются 0-основными (0-based) в которых первый символ строки имеет нулевой индекс и, более того, в некоторых языках строки относятся к неизменяемым типам.
В Delphi же до выхода Delphi XE3 нулевым индексом мы могли пользоваться, например, при работе с динамическими массивами, коллекциями, списками, не со строками. Так вот работа TStringHelper’а основана на работе с 0-основными строками, обеспечивая тем самым совместимость кода при разработке мобильных приложений.
Для работы с 0-основными строками в Delphi XE3 также появилась специальная директива компилятора ZEROBASEDSTRINGS. Пользоваться её можно следующим образом (на примере представленном выше):
{$ZEROBASEDSTRINGS ON} //включили индексирование строк на основе нуля procedure TForm6.Button1Click(Sender: TObject); var S: string; begin S:='абвгд '; ShowMessage(S[0]); //теперь тут ошибки не будет end; {$ZEROBASEDSTRINGS OFF}//отключили
По умолчанию в Delphi используются следующие настройки:
- Для десктопных приложений {$ZEROBASEDSTRINGS OFF}
- Для мобильных приложений {$ZEROBASEDSTRINGS ON}
Однако, как показано выше — никто вам не запрещает изменить эти настройки по своему усмотрению.
Что ещё следует знать про строки Delphi и TStringHelper, в частности?
С причинами появления TStringHelper разобрались. Осталось разобраться с тем, почему же нам настоятельно рекомендуют использовать TStringHelper в Delphi и при этом при любых вариантах — хоть для десктопов, хоть для мобильных устройств.
«Родные» методы работы со строками всё также используют 1-строки в работе, несмотря ни на что. Проверить это достаточно просто, например так:
{$ZEROBASEDSTRINGS ON} procedure TForm6.Button1Click(Sender: TObject); var S: string; begin S:='абвгд '; ShowMessage(pos('б',S).ToString); //тут получим "2" end; {$ZEROBASEDSTRINGS OFF}
Однако, если внимательно изучить официальную документацию по TStringHelper, то можно увидеть предостережение о том, что старые функции обработки строк в модуле System устарели, и в будущем поддержка может быть удалена.
Так что, кто бы и как не относился к TStringHelper, однако, если вы планируете использовать новейшие версии Delphi в работе, то надо приучаться использовать этот хэлпер в повседневной работе, чтобы потом не было мучительно больно за бесцельно потерянный код.