除了"%s"以外的任何内容与Variant一起使用时,为什么Format会崩溃?

RRU*_*RUZ 11 delphi variants

我正在使用SysUtils.Format函数和variant值,我发现只有格式字符串才能使用此函数%s.我检查了有关Format函数的文档,但是没有任何关于如何处理变量值的引用.

考虑这个简单的应用:

{$APPTYPE CONSOLE}

uses
  Variants,
  SysUtils;

procedure TestFormat;
var
  v : Variant;
begin
  v:=100;
  writeln(Format('The VarType of v is %s',[VarTypeAsText(VarType(v))]));
  writeln(Format('The value of v is %s',[v]));//ok

  v:='100';
  writeln(Format('The VarType of v is %s',[VarTypeAsText(VarType(v))]));
  writeln(Format('The value of v is %s',[v]));//ok

  v:=100;
  writeln(Format('The VarType of v is %s',[VarTypeAsText(VarType(v))]));
  writeln(Format('The value of v is %d',[v]));//raise a EConvertError exception EConvertError: Format '%d' invalid or incompatible with argument
end;


begin
  try
     TestFormat;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  readln;
end.
Run Code Online (Sandbox Code Playgroud)

这是一个错误还是这个功能的简单限制?

我在Delphi 5,Delphi 2007和Delphi XE中检查过这种行为.

jac*_*ate 12

这是功能的限制.在Delphi XE中,SysUtils中的相关部分从第10870行开始,如下所示:

@CvtVariant:
        CMP     CL,'S'
        JNE     @CvtError
Run Code Online (Sandbox Code Playgroud)

这适用于任何变量参数.CL寄存器具有该特定参数的格式字符串所需的类型,对于不同于"S"的任何内容,引发异常.


Rob*_*edy 10

这是功能的限制.对于功能更丰富的版本Format,请尝试WideFormat使用JCL中的函数.(我是它的作者.)它支持各种类型的变体,布尔和TClass.它还接受%p格式的字符指针类型,以及索引参数的Int64和Variant值.

尽管有它的扩展,它大约一年前从JCL发行版中删除了,因为它的主要目标是Delphi 5,它没有提供原生的WideString版本Format,而且JCL不再支持Delphi 5.包含它的最后一个版本是3140.