如何将空字符串解析为字节数组?
How to parse empty string to array of byte?
我必须使用一个旧单元,该单元在 Android 上使用 ansistring、ansichar 等,之前构建于 Delphi 2007,因此我正在努力使其与 XE7 兼容。
我遇到过几行将空字符串放入 AnsiString 的行,如下所示:FAnsiString := ''
,但现在 AnsiString 是一个字节数组 (FAnsiString : array of Byte
) 我明白了消息 E2010 类型不兼容。
我尝试通过为数组创建一个类型 (type TArrayOfByte = array of Byte
) 来解析它,并尝试像这样解析它:FAnsiString := TArrayOfByte ('')
。
但后来我得到 E2089 Invalid TypeCast.
如何让它正常工作?
下面对其工作原理进行了简化。
基本上我想要一个 returns 字节数组的函数。
根据参数,该函数的结果应该是一个空字符串。
{$ifdef android}
type AnsiString = array of Byte;
{$endif}
function FooBar(arguments) : AnsiString
begin
if false then
Result := '';
end;
Delphi 字符串和动态数组在为空时都包含一个 nil
指针。所以这个:
var
FAnsiString: AnsiString;
FAnsiString := '';
在幕后有效地执行此操作:
// FAnsiString := '';
if Pointer(FAnsiString) <> nil then
begin
// decrement reference count, if 0 then free memory ...
Pointer(FAnsiString) := nil;
end;
动态数组做完全相同的事情。这个:
var
FAnsiString: array of Byte;
FAnsiString := nil;
// Alternatively:
// SetLength(FAnsiString, 0);
实际上在做与幕后 AnsiString
清理相同的事情:
// FAnsiString := nil;
if Pointer(FAnsiString) <> nil then
begin
// decrement reference count, if 0 then free memory ...
Pointer(FAnsiString) := nil;
end;
AnsiString
和动态数组都是编译器管理的引用计数类型。它们都自动初始化为 nil
.
同样,AnsiString
比较空字符串:
var
FAnsiString: AnsiString;
if FAnsiString = '' then
...
if FAnsiString <> '' then
实际上只是在检查 nil
指针:
if Pointer(FAnsiString) = nil then
...
if Pointer(FAnsiString) <> nil then
与动态数组相同,只有你可以在没有类型转换的情况下做到这一点:
var
FAnsiString: array of byte;
if FAnsiString = nil then
...
if FAnsiString <> nil then
另一种方法是使用 Length()
和 SetLength()
,它适用于字符串和动态数组:
var
FAnsiString: AnsiString;
if Length(FAnsiString) = 0 then
...
if Length(FAnsiString) <> 0 then
...
SetLength(FAnsiString, 0);
var
FAnsiString: array of byte;
if Length(FAnsiString) = 0 then
...
if Length(FAnsiString) <> 0 then
...
SetLength(FAnsiString, 0);
当然,还有 Andreas Hausladen 的补丁可以在移动编译器中启用 AnsiString
:
The Return of the Byte-Strings
System.ByteStrings support for XE5 Update 2(以及 XE6 和 XE7)
我必须使用一个旧单元,该单元在 Android 上使用 ansistring、ansichar 等,之前构建于 Delphi 2007,因此我正在努力使其与 XE7 兼容。
我遇到过几行将空字符串放入 AnsiString 的行,如下所示:FAnsiString := ''
,但现在 AnsiString 是一个字节数组 (FAnsiString : array of Byte
) 我明白了消息 E2010 类型不兼容。
我尝试通过为数组创建一个类型 (type TArrayOfByte = array of Byte
) 来解析它,并尝试像这样解析它:FAnsiString := TArrayOfByte ('')
。
但后来我得到 E2089 Invalid TypeCast.
如何让它正常工作?
下面对其工作原理进行了简化。 基本上我想要一个 returns 字节数组的函数。 根据参数,该函数的结果应该是一个空字符串。
{$ifdef android}
type AnsiString = array of Byte;
{$endif}
function FooBar(arguments) : AnsiString
begin
if false then
Result := '';
end;
Delphi 字符串和动态数组在为空时都包含一个 nil
指针。所以这个:
var
FAnsiString: AnsiString;
FAnsiString := '';
在幕后有效地执行此操作:
// FAnsiString := '';
if Pointer(FAnsiString) <> nil then
begin
// decrement reference count, if 0 then free memory ...
Pointer(FAnsiString) := nil;
end;
动态数组做完全相同的事情。这个:
var
FAnsiString: array of Byte;
FAnsiString := nil;
// Alternatively:
// SetLength(FAnsiString, 0);
实际上在做与幕后 AnsiString
清理相同的事情:
// FAnsiString := nil;
if Pointer(FAnsiString) <> nil then
begin
// decrement reference count, if 0 then free memory ...
Pointer(FAnsiString) := nil;
end;
AnsiString
和动态数组都是编译器管理的引用计数类型。它们都自动初始化为 nil
.
同样,AnsiString
比较空字符串:
var
FAnsiString: AnsiString;
if FAnsiString = '' then
...
if FAnsiString <> '' then
实际上只是在检查 nil
指针:
if Pointer(FAnsiString) = nil then
...
if Pointer(FAnsiString) <> nil then
与动态数组相同,只有你可以在没有类型转换的情况下做到这一点:
var
FAnsiString: array of byte;
if FAnsiString = nil then
...
if FAnsiString <> nil then
另一种方法是使用 Length()
和 SetLength()
,它适用于字符串和动态数组:
var
FAnsiString: AnsiString;
if Length(FAnsiString) = 0 then
...
if Length(FAnsiString) <> 0 then
...
SetLength(FAnsiString, 0);
var
FAnsiString: array of byte;
if Length(FAnsiString) = 0 then
...
if Length(FAnsiString) <> 0 then
...
SetLength(FAnsiString, 0);
当然,还有 Andreas Hausladen 的补丁可以在移动编译器中启用 AnsiString
:
The Return of the Byte-Strings
System.ByteStrings support for XE5 Update 2(以及 XE6 和 XE7)