如何以最优雅的方式将字符数组分配给字符串?

时间:2011-10-26 19:56:02

标签: delphi syntax

我喜欢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 个答案:

答案 0 :(得分:5)

通常,

SetString是要走的路。如果人们继续对其有用性一无所知,那只是模糊不清。类型转换是必要的,因为有两个重载,并且char数组完全与预期的参数类型(PAnsiChar和PWideChar)不匹配。

这很冗长,但在您的情况下,它很容易包含在您的数据类型的函数中,例如ToString。正如David在评论中建议的那样,您可以让该函数成为Implicit运算符,然后自动获得转换:

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

S := StringStruct^;