如何在 Delphi 中将 'set of char' 转换为 'set of byte'
How to convert 'set of char' to 'set of byte' in Delphi
我是 Delphi 的新手。我试图使用 RAD studio 编译示例代码,但我收到一个编译器错误,提示类型不兼容。我看到,代码试图将类型 set of Char
的变量分配给类型 set of Byte
.
的另一个变量
Values := ABC.allowedValues;
这里Values
是set of Byte
类型,allowedValues
是set of Char
类型。
我找不到进行上述转换的方法。
很有可能(就像“几乎可以肯定”),最好的解决办法是重新设计代码。如果您确实需要这样做,可能有些事情没有以最合适的方式完成。
此外,如果您使用的是新的 Delphi 版本(2009 或更新版本),Char
是一个两字节的 Unicode 字符,因此没有“真”这样的东西set of Char
,因为 Delphi set 的基类型必须是最多有 256 个不同值的序数类型。 (两个字节表示 65 536 个不同的值。)
2009年Delphi之前,Char
确实是单字节字符;在引擎盖下它只是一个 Byte
。今天,Char = WideChar
而 AnsiChar
是旧的单字节字符类型。
因此,让我们假设您使用的是 Unicode 之前的 Delphi 版本,或者您实际使用的是 set of AnsiChar
。如果您在现代 Delphi 版本中编写 set of Char
,编译器将“帮助”将其解释为 set of AnsiChar
并为您提供 warning.
执行转换的“缓慢”但真正类型安全的方法如下:
type
TCharSet = set of AnsiChar;
TByteSet = set of Byte;
function SetConvert(ACharSet: TCharSet): TByteSet;
begin
Result := [];
for var c in ACharSet do
Include(Result, Ord(c))
end;
这利用了 Delphi 10.3 中引入的内联变量和 Delphi 2005 中引入的 for..in
循环 (?)。 10.3之前,你需要写
function SetConvert(ACharSet: TCharSet): TByteSet;
var
c: AnsiChar;
begin
Result := [];
for c in ACharSet do
Include(Result, Ord(c))
end;
最后,您的问题严格来说没有明确定义,因为您没有指定如何将字符集映射到字节集。在上面,我假设您想使用由基本类型之间的 Ord/Chr
映射引起的映射。
变体 A:
uses
System.SysUtils;
type
TCharSet = set of AnsiChar;
TByteSet = set of Byte;
TMySet=packed record
case char of
'A': (a : TCharSet);
'B': (b : TByteSet);
end;
var
x: TMySet;
i: integer;
begin
try
x.a := ['a', 'z', 'A'..'Z'];
for i in x.b do
write(i, ', ');
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
结束。
变体 B:
uses
System.SysUtils;
type
TCharSet = set of AnsiChar;
TByteSet = set of Byte;
var
a: TCharSet;
b: TByteSet absolute a;
i: integer;
begin
try
a := ['a', 'z', 'A'..'Z'];
for i in b do
write(i, ', ');
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
我是 Delphi 的新手。我试图使用 RAD studio 编译示例代码,但我收到一个编译器错误,提示类型不兼容。我看到,代码试图将类型 set of Char
的变量分配给类型 set of Byte
.
Values := ABC.allowedValues;
这里Values
是set of Byte
类型,allowedValues
是set of Char
类型。
我找不到进行上述转换的方法。
很有可能(就像“几乎可以肯定”),最好的解决办法是重新设计代码。如果您确实需要这样做,可能有些事情没有以最合适的方式完成。
此外,如果您使用的是新的 Delphi 版本(2009 或更新版本),Char
是一个两字节的 Unicode 字符,因此没有“真”这样的东西set of Char
,因为 Delphi set 的基类型必须是最多有 256 个不同值的序数类型。 (两个字节表示 65 536 个不同的值。)
2009年Delphi之前,Char
确实是单字节字符;在引擎盖下它只是一个 Byte
。今天,Char = WideChar
而 AnsiChar
是旧的单字节字符类型。
因此,让我们假设您使用的是 Unicode 之前的 Delphi 版本,或者您实际使用的是 set of AnsiChar
。如果您在现代 Delphi 版本中编写 set of Char
,编译器将“帮助”将其解释为 set of AnsiChar
并为您提供 warning.
执行转换的“缓慢”但真正类型安全的方法如下:
type
TCharSet = set of AnsiChar;
TByteSet = set of Byte;
function SetConvert(ACharSet: TCharSet): TByteSet;
begin
Result := [];
for var c in ACharSet do
Include(Result, Ord(c))
end;
这利用了 Delphi 10.3 中引入的内联变量和 Delphi 2005 中引入的 for..in
循环 (?)。 10.3之前,你需要写
function SetConvert(ACharSet: TCharSet): TByteSet;
var
c: AnsiChar;
begin
Result := [];
for c in ACharSet do
Include(Result, Ord(c))
end;
最后,您的问题严格来说没有明确定义,因为您没有指定如何将字符集映射到字节集。在上面,我假设您想使用由基本类型之间的 Ord/Chr
映射引起的映射。
变体 A:
uses
System.SysUtils;
type
TCharSet = set of AnsiChar;
TByteSet = set of Byte;
TMySet=packed record
case char of
'A': (a : TCharSet);
'B': (b : TByteSet);
end;
var
x: TMySet;
i: integer;
begin
try
x.a := ['a', 'z', 'A'..'Z'];
for i in x.b do
write(i, ', ');
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
结束。
变体 B:
uses
System.SysUtils;
type
TCharSet = set of AnsiChar;
TByteSet = set of Byte;
var
a: TCharSet;
b: TByteSet absolute a;
i: integer;
begin
try
a := ['a', 'z', 'A'..'Z'];
for i in b do
write(i, ', ');
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.