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

Pre*_*ion 3 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;
Run Code Online (Sandbox Code Playgroud)

如果有人想要正式的问题:我想看看我必须执行哪些选项,最好不要比显示的SetString电话更模糊.

注意:我知道解除引用运算符对于结构化类型是可选的.

Rob*_*edy 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^;
Run Code Online (Sandbox Code Playgroud)

  • 类操作符与类方法一样,对类型布局完全没有影响.它们只是普通的独立功能,但具有特殊的范围.类助手只允许用于类,而不是记录,并且无论如何都不适合. (2认同)