【发布时间】:2015-11-25 22:13:30
【问题描述】:
是否可以将空(零)TDateTime 值表示为常数?我尝试了TDateTime(0)、TDateTime(0.0) 和其他东西,但编译器(Delphi 7)并没有留下深刻的印象。
目前我正在使用一个初始化的全局变量:
const
TDateTime_0: TDateTime = 0.0;
这类作品。但是,我只是继承了一大堆很好的 Delphi 7 代码,而且我已经很久没有使用过 Turbo Pascal 了……这意味着我真的需要重新学习我的 Delphi fu,这让我很想知道。
相比之下,编译器对Integer(0) 之类的东西非常满意。将其分配给变体会产生 ftInteger 类型的值 0,而分配纯文字 0 会产生 ftSmallInt 类型的变体。
澄清:目标是将特定类型的“空”值传递给接受变体的函数(其中包括编译器管理的变体数组,称为“const 数组”以及诸如 TParameter.Value 之类的设置器)。
Ken White 的澄清:这里的问题本质上是类型推导和重载解析;上面提到的“采用变体的函数”只是一个特例。文字0 和0.0 可以隐式转换为TDateTime,这就是为什么它们可以分配给那种类型的容器(变量、记录字段)并且它们可以用来初始化这样的容器(即函数参数),而无需再多说一句。但是,当编译器需要进行类型推导时,情况就会发生变化:
procedure foo (value: Double); overload;
procedure foo (value: TDateTime); overload;
在这两种情况下,基础类型都是 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;
我的问题是/只是是否可以像示例中的Integer 和TSomeId 一样形成TDateTime 类型(或基于Double 的其他类型)的表达式上面,没有为此目的分配和初始化类型化的内存位置。但是,Yuriy 的回答表明这仅适用于序数类型。
【问题讨论】:
-
我问的是一个编译时常量表达式,它被标记为
TDateTime类型,就像Integer(0)的类型是Integer而不是SmallInt作为普通 (' untyped') 文字0将是。我故意避免使用“类型常量”这个术语,因为 Borland/Embarcadero 的知识将它用于只读初始化变量,这不是一回事。表达式的确切类型 - 常量或其他 - 在编译器需要进行类型推导的上下文中是相关的;分配给(或初始化)变体是一种情况,重载决议是另一种情况。 -
@KenWhite 基本上他抱怨 Delphi 违反了自己的
type x = TYPE y构造,该构造应该是一个完全不相关的类型,没有隐式类型转换。有点类似于我的抱怨stackoverflow.com/questions/11029353 -
@DarthGizka 我相信你可以尝试在最近的 Delphi 中使用
Advanced Records+Operators Overloading即implicit type-cast来实现。如果您的记录将有隐式的内联类型转换到/从 TDateTime 但不是到/从 double 比可能 - 也许 - 它可以工作。然而,对于这些概念来说,Delphi 7 太旧了。不知道关于 FPC/Lazarus/CodeTyphon -
您的最后一次编辑使问题更加清晰。谢谢你这样做。 :-)