【问题标题】:How to assign character array to string in the most elegant manner?如何以最优雅的方式将字符数组分配给字符串?
【发布时间】:2011-10-26 19:56:02
【问题描述】:

我喜欢 Pascal 的清晰性,因此请相信以下代码 sn-p 以及问题标题是不言自明的:

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 电话显示的更隐蔽。

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

【问题讨论】:

  • 看起来你正在实现一些类似 Pascal 字符串的东西。您可以尝试使用运算符重载。重载隐式和显式转换运算符。附言在选民徽章上做得很好!
  • 如果你不知道;您可以使用双反斜杠注释掉一行代码,而不是用大括号括起来,例如"// 这个结构仅仅定义了内存布局"

标签: delphi syntax


【解决方案1】:

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^;

【讨论】:

  • 是的,有时重载会增加复杂性,而不是解决它们。明白了你对匹配类型的看法,谢谢。
  • 运算符方法看起来很优雅,但请您澄清一下:a)类方法会干扰结构的内存布局吗? b)我可以使用类助手之类的东西来隔离检测结构吗? c) 记录运算符的最低编译器版本要求是 BDS2006,对吧?
  • 类操作符和类方法一样,对类型布局完全没有影响。它们只是普通的独立函数,但具有特殊的范围。类助手只允许用于类,而不是记录,无论如何在这里都不合适。
猜你喜欢
  • 1970-01-01
  • 2011-04-25
  • 1970-01-01
  • 2012-03-25
  • 2010-10-09
  • 1970-01-01
  • 2011-08-07
  • 2021-11-26
相关资源
最近更新 更多