是否可以将空(零)TDateTime 值表示为常量?我试过TDateTime(0),TDateTime(0.0)和其他东西,但编译器 (Delphi 7) 没有留下深刻的印象。
目前我正在使用一个初始化的全局变量:
const
TDateTime_0: TDateTime = 0.0;
Run Code Online (Sandbox Code Playgroud)
这样的作品。然而,我只是继承了一大堆很好的Delphi 7代码,而且我已经好久没有使用Turbo Pascal了......这意味着我真的需要刷我的Delphi fu,这让我想知道。
相比之下,编译器对类似Integer(0). 它分配给一个变体的结果是类型 0 的值ftInteger,而分配一个普通文字 0 将导致一个类型的变体ftSmallInt。
澄清:目标是将特定类型的“空”值传递给采用变体的函数(包括编译器管理的变体数组,称为“常量数组”,以及诸如 TParameter.Value 之类的设置器)。
对 Ken White 的澄清:这里的问题本质上是类型推导和重载解析;上面提到的“采用变体的函数”只是一个特例。文字0and0.0可以隐式转换为TDateTime,这就是为什么它们可以分配给该类型的容器(变量、记录字段),并且它们可以用于初始化此类容器(即函数参数),无需多说。但是,当编译器需要进行类型推导时,情况发生了变化:
procedure foo (value: Double); overload;
procedure foo (value: TDateTime); overload;
Run Code Online (Sandbox Code Playgroud)
在这两种情况下,底层类型都是 Double,这意味着编译器需要显式键入参数(即,使用纯文字的调用被拒绝为不明确的)。对于基于序数的类型,显式类型没有问题,但类型 Double 有问题,需要将值填充到类型化容器中才能使用它们。可编译示例(需要比 Delphi 7 新的 Delphi):
type
TSomeId = type Integer;
procedure foo (value: Integer ); overload; begin WriteLn('Integer ', value); end;
procedure foo (value: TSomeId ); overload; begin WriteLn('TSomeId ', value); end;
procedure foo (value: Double ); overload; begin WriteLn('Double ', value); end;
procedure foo (value: TDateTime); overload; begin WriteLn('TDateTime ', value); end;
procedure test_TYPE_Double;
var
d: Double;
t: TDateTime;
begin
foo(Integer(0));
foo(TSomeId(0));
d := 0; foo(d);
t := 0; foo(t);
end;
Run Code Online (Sandbox Code Playgroud)
我的问题是/只是是否有可能以与上面示例相同的方式形成类型TDateTime(或基于 的其他类型Double)的表达式,而无需为此目的分配和初始化类型化的内存位置。但是,Yuriy 的回答表明这仅适用于序数类型。IntegerTSomeId
编译器可以将序数类型转换为其他序数类型,但拒绝将浮点类型相互转换,即使它们完全相同:
TMyOwnDouble = type double;
...
var a,b: TMyOwnDouble;
...
a:=MyOwnDouble(0.0); //invalid typecast
b:=0.0; //no problem
Run Code Online (Sandbox Code Playgroud)
你到底想要什么?如果需要这个 TDateTime 常量只是为了将其传递给需要 TDateTime 的某个函数,那么您只需传递 0.0 就可以了:
caption:=DateTimeToStr(0.0); //it shows 30.12.1899
Run Code Online (Sandbox Code Playgroud)
有两个功能可能很方便:
function FloatToDateTime(const Value: Extended): TDateTime; //sysUtils unit
Run Code Online (Sandbox Code Playgroud)
它检查值的边界,如果没问题,则进行单个分配。
function VarFromDateTime(DateTime: TDateTime): Variant; //Variants unit
Run Code Online (Sandbox Code Playgroud)
这显式创建了 DateTime 变体。我在这样的代码中尝试了它们,它们的工作原理相同:
var V: Variant;
...
V:=VarFromDateTime(0.0);
//V:=FloatToDateTime(0.0); //works as well
Caption:=V; //shows 0:00:00
Run Code Online (Sandbox Code Playgroud)
这样的代码可能比使用 TDateTime_0 常量更容易理解,但它有点庞大。