Mik*_*nni 3 delphi string char compiler-warnings delphi-xe7
我有一个简单的函数,可以将数字转换为字符串(类似于Excel列号1..n可以转换为列名的方式A-ZZZ).由于我经常使用它,我已经删除了局部变量作为速度优化,并且只能Result直接使用.
当我编译时,我得到这两个警告:
W1047不安全代码'var param的字符串索引'
W1068将来可能不支持修改字符串
这是缩短的功能:
function Idx2Code_(Idx: integer): string;
begin
SetLength(Result, 3); // init Result size
if Idx <= 26 then
begin
// single char: A-Z
Result := Chr(64 + Idx);
SetLength(Result, 1);
end
else if Idx <= 676 then
begin
// 2 chars codes: BA-ZZ
Result[1] := Chr((Idx div 26) + 64 + 1); // <- warnings for this line
Result[2] := Chr((Idx mod 26) + 64); // <- warnings for this line
SetLength(Result, 2);
end
else
begin
// 3 chars codes: BAA-ZZZ
Result[1] := Chr((Idx div 676) + 64 + 1); // <- warnings for this line
Result[2] := Chr(((Idx mod 676) div 26) + 64 + 26); // <- warnings for this line
Result[3] := Chr((Idx mod 26) + 64 + 26); // <- warnings for this line
end;
end;
Run Code Online (Sandbox Code Playgroud)
我可以使用局部变量,但它较慢,我不想要.
我不想在将来的Delphi版本中使用可能变得"过时"的代码.
如何解决警告,但尽可能保持简单性和速度?
在移动开发中,默认情况下,Delphi string类型的直接索引是基于0的(可以使用该{$ZEROBASEDSTRINGS OFF}指令禁用).
在桌面开发中,默认情况下,直接索引仍然是基于1的,但将来可能会从 0开始.
由于平台之间存在这种差异string,因此不鼓励直接编制索引,从而发出警告消息.为避免这种情况,TStringHelper.Chars[]所有平台都提供基于0的属性.但是,这个属性是只读的,所以你不能用它来修改一个内容string(在某一点上,Embarcadero正在考虑制作string不可变的,但后来决定反对它,但警告仍然存在).
在这种情况下,您将不得不:
禁用警告,并使用适合平台的索引.您可以用它Low(string)来帮助您:
{$WARN UNSAFE_CODE OFF}
{$WARN IMMUTABLE_STRINGS OFF}
function Idx2Code_(Idx: integer): string;
begin
if Idx <= 26 then
begin
// single char: A-Z
SetLength(Result, 1);
Result[Low(string)] := Chr(64 + Idx);
end
else if Idx <= 676 then
begin
// 2 chars codes: BA-ZZ
SetLength(Result, 2);
Result[Low(string)] := Chr((Idx div 26) + 64 + 1);
Result[Low(string)+1] := Chr((Idx mod 26) + 64);
end
else
begin
// 3 chars codes: BAA-ZZZ
SetLength(Result, 3);
Result[Low(string)] := Chr((Idx div 676) + 64 + 1);
Result[Low(string)+1] := Chr(((Idx mod 676) div 26) + 64 + 26);
Result[Low(string)+2] := Chr((Idx mod 26) + 64 + 26);
end;
end;
{$WARN IMMUTABLE_STRINGS DEFAULT}
{$WARN UNSAFE_CODE DEFAULT}
Run Code Online (Sandbox Code Playgroud)用一个TStringBuilder:
uses
System.SysUtils;
function Idx2Code_(Idx: integer): string;
var
SB: TStringBuilder;
begin
SB := TStringBuilder.Create(3);
try
if Idx <= 26 then
begin
// single char: A-Z
SB.Append(Chr(64 + Idx));
end
else if Idx <= 676 then
begin
// 2 chars codes: BA-ZZ
SB.Append(Chr((Idx div 26) + 64 + 1));
SB.Append(Chr((Idx mod 26) + 64));
end
else
begin
// 3 chars codes: BAA-ZZZ
SB.Append(Chr((Idx div 676) + 64 + 1));
SB.Append(Chr(((Idx mod 676) div 26) + 64 + 26));
SB.Append(Chr((Idx mod 26) + 64 + 26));
end;
Result := SB.ToString;
finally
SB.Free;
end;
end;
Run Code Online (Sandbox Code Playgroud)
或者,TStringbuilder它有自己的Chars[]可写属性:
uses
System.SysUtils;
function Idx2Code_(Idx: integer): string;
var
SB: TStringBuilder;
begin
SB := TStringBuilder.Create(3);
try
if Idx <= 26 then
begin
// single char: A-Z
SB.Length := 1;
SB[0] := Chr(64 + Idx);
end
else if Idx <= 676 then
begin
// 2 chars codes: BA-ZZ
SB.Length := 2;
SB[0] := Chr((Idx div 26) + 64 + 1);
SB[1] := Chr((Idx mod 26) + 64);
end
else
begin
// 3 chars codes: BAA-ZZZ
SB.Length := 3;
SB[0] := Chr((Idx div 676) + 64 + 1);
SB[1] := Chr(((Idx mod 676) div 26) + 64 + 26);
SB[2] := Chr((Idx mod 26) + 64 + 26);
end;
Result := SB.ToString;
finally
SB.Free;
end;
end;
Run Code Online (Sandbox Code Playgroud)有关更多信息,请参阅Embarcadero的文档:
| 归档时间: |
|
| 查看次数: |
387 次 |
| 最近记录: |