Почему формат разбивается, когда что-либо, кроме "% s", используется с вариантом?

Я работаю с 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.

Является ли это ошибкой или простым ограничением этой функции?

Я проверил это поведение в Delphi 5, Delphi 2007 и Delphi XE.

Ответ 1

Это ограничение функции. В Delphi XE соответствующая часть в SysUtils начинается с строки 10870, которая выглядит следующим образом:

@CvtVariant:
        CMP     CL,'S'
        JNE     @CvtError

Это вызвано для любого варианта аргумента. Регистр CL имеет тип, требуемый строкой формата для этого конкретного аргумента, для чего-либо другого, чем "S", исключение возникает.

Ответ 2

Это ограничение функции. Для более функциональной версии Format попробуйте функцию WideFormat из JCL. (Я его автор.) Он поддерживает варианты различных типов, булевых и TClass. Он также принимает типы символов-указателей для формата %p, а также значения Int64 и Variant для аргументов индекса.

Несмотря на свои расширения, он был удален из дистрибутива JCL примерно год назад, поскольку его основной целью был Delphi 5, который не предоставил собственную версию WideString Format, а JCL больше не поддерживает Delphi 5. последняя версия, которая включала в себя 3140.