【问题标题】:How to use Include with Unicode?如何使用包含 Unicode?
【发布时间】:2012-09-29 23:25:18
【问题描述】:

我正在尝试将一些代码从 D2007 移植到 DXE2。 这个简化的代码在 D2007 中编译得很好。在 DXE2 中显示此错误:

[DCC Warning] Unit1.pas(10): W1050 WideChar reduced to byte char in set expressions.  Consider using 'CharInSet' function in 'SysUtils' unit.
[DCC Error] Unit1.pas(37): E2010 Incompatible types: 'AnsiChar' and 'Char'

可能是 unicode 问题。 谁能告诉我为什么会发生这种情况以及我应该如何纠正它?

问候

代码:

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs;

type
  TSetOfChar = Set of Char;  // Line 10

  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    FCharacterSet: TSetOfChar;
  public
    property CharacterSet: TSetOfChar read FCharacterSet write FCharacterSet;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var
  CharacterSet: TSetOfChar;
  j: Integer;
  s: String;
begin
  CharacterSet := [];
  s := 'I''m just testing åäö';

  for j := 1 to Length(s) do
    Include(CharacterSet, s[j]);  // <- Line 37

end;

end.

编辑:请注意,我使用的是没有泛型的 Delphi 2007。我想要在 D2007 中仍然有效的代码,因为有很多代码可以移植到 Unicode。这是一个缓慢的过程。 当一切都被移植,验证它与 XE2 一起工作,然后我们可以使用 XE2 的东西,比如泛型。与此同时,我们照常维护 D2007,我们希望避免在版本控制系统中创建 XE2 分支。

【问题讨论】:

  • 我认为 Dictionary 类型可能会提供与 Delphi 集合类型的“if x in set”操作相当的运行时速度,请考虑改用字典。包含将成为“如果还不是字典的一部分,则添加此键”对具有 Widechar 键的字典的操作。

标签: delphi delphi-xe2 delphi-2007


【解决方案1】:

这是标准的 Unicode Delphi 迁移素材。必读是 Marco Cantù 的论文 White Paper: Delphi and Unicode。如果您还没有阅读,请阅读。如果您最近没有读过,请再读一遍。

set of char 产生警告的原因是集合的基本类型不能超过 256 个值。但是由于 char 现在是 UTF-16,这比 256 多很多。这意味着您的代码永远无法使用集合和 UTF-16 字符。

您可以使用set of AnsiChar 和AnsiString。但是,如果您希望此代码适用于 Unicode 数据,那么您需要使用 set 以外的其他内容。例如可以使用TList&lt;char&gt;。

var
  CharacterSet: TList<char>;
  s: string;
  c: char;
.....
CharacterSet := TList<char>.Create;
s := 'I''m just testing åäö';
for c in s do
  if not CharacterSet.Contains(c) then
    CharacterSet.Add(c);

我不建议将其用于生产。它的性能特征将是可怕的。基于哈希的字典会做得更好。最棒的是一个专门的大型集合类。

最后一点。字符与 UTF-16 中的代码点不同,UTF-16 是一种可变长度编码。有问题的代码和这个答案没有考虑到这一点。

【讨论】:

  • +许多Characters are not the same as code points in UTF-16 which is a variable length encoding.
  • 请注意,我使用的是没有泛型的 Delphi 2007。也许 TStringlist.Value 是这里的最佳选择?
  • 如果您使用的是 D2007,那么您没有 Unicode,这是毫无疑问的。这个问题只对 Unicode Delphi 有意义。
  • 是的,我同意 :) 但问题是我想要在 Delphi 2007 和 Delphi XE2 中都可以使用的代码。移植到 XE2 是一个缓慢的过程,一周内无法完成。所以所有代码都必须在 Delphi 2007 中运行,直到我们在实际环境中部署所有内容。
  • 您不能在 XE2 中使用 set of char。我想我回答了你问的问题。你不能指望我就如何设计你的移植策略给你建议。我没有足够的信息和背景来做到这一点。
猜你喜欢
  • 1970-01-01
  • 2020-05-06
  • 2011-01-28
  • 1970-01-01
  • 2019-06-04
  • 2013-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多