gpt4 book ai didi

delphi - Delphi XE4 中的 CharInSet 编译器警告

转载 作者:行者123 更新时间:2023-12-03 14:58:49 25 4
gpt4 key购买 nike

我的 Delphi 7 代码中有以下语句。

TMyCharSet = set of char;

当我将该代码迁移到 Delphi XE4 时,我在上面的行中收到以下编译器警告。

W1050 WideChar reduced to byte char in set expressions.  Consider using 'CharInSet' function in 'SysUtils' unit.

我应该如何重新声明 TMyCharSet?

最佳答案

集合不能包含大于一个字节的项目。自 Char在 Unicode Delphi 中是 WideChar它的大小为两个字节,集合类型是不合适的容器。

以下是基于记录的通用集类型的示例 TSet<T> 。这意味着您不必考虑这种类型的变量的创建和销毁。使用此类型作为简单类型的容器。我试图模仿集合类型的大部分行为。项目的加法和减法可以使用 + 和 - 运算符来完成。添加了in也是运算符。

注意:记录将数据保存在动态数组中。将一个变量分配给另一个变量将使两个变量使用相同的动态数组。内置的写入时复制 (COW) 保护将防止一个变量的更改反射(reflect)到另一个变量上。

unit GenericSet;

interface

Uses
System.Generics.Defaults;

Type
TSet<T> = record
class operator Add(const aSet: TSet<T>; aValue: T) : TSet<T>; overload;
class operator Add(const aSet: TSet<T>; const aSetOfT: TArray<T>) : TSet<T>; overload;
class operator Add(const aSet1: TSet<T>; const aSet2: TSet<T>) : TSet<T>; overload;
class operator Subtract(const aSet: TSet<T>; aValue: T): TSet<T>; overload;
class operator Subtract(const aSet: TSet<T>; const aSetOfT: TArray<T>) : TSet<T>; overload;
class operator Subtract(const aSet1: TSet<T>; const aSet2: TSet<T>) : TSet<T>; overload;
class operator In(aValue: T; const aSet: TSet<T>): Boolean; overload;
class operator In(const aSetOf: TArray<T>; const aSet: TSet<T>): Boolean; overload;
class operator In(const aSet1: TSet<T>; const aSet2: TSet<T>): Boolean; overload;
private
FSetArray : TArray<T>;
function GetEmpty: Boolean;
public
procedure Add(aValue: T);
procedure AddSet(const setOfT: array of T); overload;
procedure AddSet(const aSet: TSet<T>); overload;
procedure Remove(aValue: T);
procedure RemoveSet(const setOfT: array of T); overload;
procedure RemoveSet(const aSet : TSet<T>); overload;
function Contains(aValue: T): Boolean; overload;
function Contains(const aSetOfT: array of T): Boolean; overload;
function Contains(const aSet : TSet<T>): Boolean; overload;
procedure Clear;
property Empty: Boolean read GetEmpty;
end;

implementation

procedure TSet<T>.Add(aValue: T);
begin
if not Contains(aValue) then begin
SetLength(FSetArray,Length(FSetArray)+1);
FSetArray[Length(FSetArray)-1] := aValue;
end;
end;

class operator TSet<T>.Add(const aSet: TSet<T>; aValue: T): TSet<T>;
begin
Result.AddSet(aSet.FSetArray);
Result.Add(aValue);
end;

class operator TSet<T>.Add(const aSet: TSet<T>; const aSetOfT: TArray<T>): TSet<T>;
begin
Result.AddSet(aSet.FSetArray);
Result.AddSet(aSetOfT);
end;

class operator TSet<T>.Add(const aSet1, aSet2: TSet<T>): TSet<T>;
begin
Result.AddSet(aSet1.FSetArray);
Result.AddSet(aSet2.FSetArray);
end;

procedure TSet<T>.AddSet(const setOfT: array of T);
var
i : Integer;
begin
for i := 0 to High(setOfT) do
Self.Add(setOfT[i]);
end;

procedure TSet<T>.AddSet(const aSet: TSet<T>);
begin
AddSet(aSet.FSetArray);
end;

procedure TSet<T>.RemoveSet(const setOfT: array of T);
var
i : Integer;
begin
for i := 0 to High(setOfT) do
Self.Remove(setOfT[i]);
end;

procedure TSet<T>.RemoveSet(const aSet: TSet<T>);
begin
RemoveSet(aSet.FSetArray);
end;

class operator TSet<T>.Subtract(const aSet1, aSet2: TSet<T>): TSet<T>;
begin
Result.AddSet(aSet1.FSetArray);
Result.RemoveSet(aSet2.FSetArray);
end;

class operator TSet<T>.Subtract(const aSet: TSet<T>;
const aSetOfT: TArray<T>): TSet<T>;
begin
Result.AddSet(aSet.FSetArray);
Result.RemoveSet(aSetOfT);
end;

class operator TSet<T>.Subtract(const aSet: TSet<T>; aValue: T): TSet<T>;
begin
Result.AddSet(aSet.FSetArray);
Result.RemoveSet(aValue);
end;

class operator TSet<T>.In(aValue: T; const aSet: TSet<T>): Boolean;
begin
Result := aSet.Contains(aValue);
end;

class operator TSet<T>.In(const aSetOf: TArray<T>; const aSet: TSet<T>): Boolean;
begin
Result := aSet.Contains(aSetOf);
end;

class operator TSet<T>.In(const aSet1: TSet<T>; const aSet2: TSet<T>): Boolean;
begin
Result := aSet2.Contains(aSet1.FSetArray);
end;

function TSet<T>.Contains(aValue: T): Boolean;
var
i : Integer;
c : IEqualityComparer<T>;
begin
c := TEqualityComparer<T>.Default;
Result := false;
for i := 0 to Length(FSetArray)-1 do
if c.Equals(FSetArray[i],aValue) then
Exit(True);
end;

function TSet<T>.GetEmpty: Boolean;
begin
Result := (Length(FSetArray) = 0);
end;

procedure TSet<T>.Clear;
begin
SetLength(FSetArray,0);
end;

function TSet<T>.Contains(const aSetOfT: array of T): Boolean;
var
i : Integer;
begin
Result := High(aSetOfT) >= 0;
for i := 0 to High(aSetOfT) do
begin
Result := Contains(ASetOfT[i]);
if not Result then
Exit(false);
end;
end;

function TSet<T>.Contains(const aSet: TSet<T>): Boolean;
begin
Result := Contains(aSet.FSetArray);
end;

procedure TSet<T>.Remove(aValue: T);
var
i : Integer;
c : IEqualityComparer<T>;
begin
c := TEqualityComparer<T>.Default;
for i := 0 to Length(FSetArray)-1 do
begin
if c.Equals(FSetArray[i],aValue) then
begin
SetLength(FSetArray,Length(FSetArray)); // Ensure unique dyn array
if (i < Length(FSetArray)-1) then
FSetArray[i] := FSetArray[Length(FSetArray)-1]; // Move last element
SetLength(FSetArray,Length(FSetArray)-1);
Break;
end;
end;
end;

end.
<小时/>

示例测试程序:

program ProjectGenericSet;
{$APPTYPE CONSOLE}
uses
GenericSet in 'GenericSet.pas';

var
mySet,mySet1 : TSet<Char>;
begin
mySet.AddSet(['A','B','C']);
WriteLn(mySet.Contains('C'));
WriteLn(mySet.Contains('D')); // False
mySet := mySet + 'D';
WriteLn(mySet.Contains('D'));
WriteLn('D' in mySet);
mySet := mySet - 'D';
WriteLn(mySet.Contains('D')); // False
mySet := mySet + TArray<Char>.Create('D','E');
WriteLn(mySet.Contains('D'));
WriteLn(mySet.Contains(['A','D']));
mySet1 := mySet;
// Testing COW
mySet1.Remove('A');
WriteLn(mySet.Contains('A'));
mySet1:= mySet1 + mySet;
WriteLn(mySet1.Contains('A'));
mySet := mySet1;
mySet1.Clear;
WriteLn(mySet.Contains('A'));
ReadLn;
end.

关于delphi - Delphi XE4 中的 CharInSet 编译器警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19419239/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com