Как назначить массив символов для строки самым элегантным способом? - PullRequest
3 голосов
/ 26 октября 2011

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

procedure TForm1.FormClick(Sender: TObject);
const
  N = 42; { fnord }
type
  { this structure merely defines memory layout }
  TStringStruct = record
    NumberOfCharacters: Cardinal;
    { this array supposed to be friendly for the string type }
    StringCompatibleArray: array [0..N-1] of Char;
  end;
  { actual work is done with pointer to that structure }
  PStringStruct = ^TStringStruct;
var
  StringStruct: PStringStruct;
  S: string;
begin
  StringStruct := PopulatedElsewhere;

  { most pleasant code but will copy no more than N characters }
  S := StringStruct^.StringCompatibleArray;

  { this construct works but is way too ugly and complex }
  SetString(
    S,
    { in particular: must reference the array and then typecast to make it work }
    { default $T- state assumed, unfortunately $T+ has global effect and not useful here }
    PChar(@StringStruct^.StringCompatibleArray),
    StringStruct^.NumberOfCharacters
  );
end;

В случае, если кто-то хочет получить официальный вопрос: я хотел бы посмотреть, какие вариантымне нужно выполнить такое назначение, желательно менее смутное, чем показанный SetString вызов.

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

1 Ответ

5 голосов
/ 27 октября 2011

SetString - это путь, обычно.Это только неясно, если люди продолжают оставаться в неведении о его полезности.Приведение типов необходимо, потому что есть две перегрузки, и массив char не точно соответствует ни одному из ожидаемых типов аргументов (PAnsiChar и PWideChar).

Это многословно, но в вашем случаелегко оборачивается в функцию для вашего типа данных, например ToString.Как сказал Дэвид в комментарии, вы можете разрешить этой функции быть оператором Implicit, а затем автоматически получите преобразование:

class operator TStringStruct.Implicit(const Value: TStringStruct): string;
begin
  SetString(Result, Value.StringCompatibleArray, Value.NumberOfCharacters);
end;

S := StringStruct^;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...