能否用一个常量表示空(零)TDateTime值呢?我尝试过 TDateTime(0)
, TDateTime(0.0)
等等,但是编译器(Delphi 7)并不认可。
目前我使用一个已初始化的全局变量:
const
TDateTime_0: TDateTime = 0.0;
这种方法基本可行。但是,我刚继承了一大堆Delphi 7的代码,而我已经很久没有使用Turbo Pascal了...这意味着我需要认真恢复我的Delphi技能,这让我想知道更多。
相比之下,编译器对于
Integer(0)
这样的内容非常满意。它被分配给变体后,结果为类型为ftInteger
的值0,而将普通文字0分配给变体会导致一个类型为ftSmallInt
的变体。澄清一下:目标是传递特定类型的“空”值给接受变体的函数(包括编译器管理的变体数组,即“array of 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
一样,在不分配和初始化类型化内存位置的情况下,以相同的方式形成基于Double
的其他类型或TDateTime
类型的表达式。然而,Yuriy的答案表明这只适用于序数类型。
TDateTime
,就像Integer(0)
与普通(“未标记”)字面值0
的类型不同一样。我故意避免使用“有类型常量”这个术语,因为 Borland/Embarcadero 的传统用法是指只读初始化变量,这并不是同一回事。一个表达式 - 常量或其他 - 的确切类型在编译器需要进行类型推导的上下文中是相关的;对变体的赋值(或初始化)就是这种情况之一,重载分辨率是另一种情况。 - DarthGizkatype x = TYPE y
结构,这应该创建一个完全不相关的类型,没有隐式类型转换。有点类似于我的抱怨https://dev59.com/6mgu5IYBdhLWcg3w2ahm - Arioch 'The高级记录
+运算符重载
,即隐式类型转换
。如果你的记录具有从TDateTime到double的隐式内联类型转换,但没有从double到TDateTime的隐式内联类型转换,那么也许 - 也许 - 它可以工作。 然而,Delphi 7对于这些概念来说太过陈旧。不知道FPC/Lazarus/CodeTyphon如何。 - Arioch 'The