Freepascal 拉扎勒斯(自由帕斯卡)。看似不必要的编译器警告

Freepascal 拉扎勒斯(自由帕斯卡)。看似不必要的编译器警告,freepascal,lazarus,Freepascal,Lazarus,我对释放帕斯卡和拉扎勒斯还不熟悉。我正在测试新的“高级记录”功能,并得到一个看起来不必要的编译器警告 代码非常简单,只是一条记录,用一个方法初始化数据字段。比如: {$mode delphi} type TTest = record a,b: double; procedure Init(x,y: double); end procedure TTest.Init(x,y: double); begin test.a := x; test.b := y; en

我对释放帕斯卡和拉扎勒斯还不熟悉。我正在测试新的“高级记录”功能,并得到一个看起来不必要的编译器警告

代码非常简单,只是一条记录,用一个方法初始化数据字段。比如:

{$mode delphi}

type TTest =
  record
    a,b: double;
    procedure Init(x,y: double);
  end

procedure TTest.Init(x,y: double);
begin
  test.a := x;
  test.b := y;
end;


var t: TTest;
begin
  t.Init(0.1,0.2);
最后一行显示为“t.Init()”,它总是生成一个编译器警告,指出“变量“t”似乎尚未初始化

好吧,这只是一个警告,所以很明显我可以接受,但我只是想确保这不是因为我的一些潜在误解


编辑以添加新信息。

重新定义方法verus Constructor point。 再进一步研究一下,我有点高兴FPC不允许构造函数进行记录。Delphi有构造函数,但没有析构函数,据我所知,构造函数(用于记录)完全不做方法不能做的事情。我是一个极简主义者,所以对我来说,没有必要使用额外的语法,这些语法只做一些现有语法所做的事情

特别是对于这样一个简单的记录,声明它的行为(var t:TTest)完成了该记录需要的所有“构造”。其他任何东西(比如我的Init)都只是设置值,而不是构造任何东西。就我所知,构造函数不是答案,编译器只需要删除警告

在研究这个问题时,我遇到了另一种常用的技术,即所谓的“工厂功能”。也就是说,记录外部的函数,例如:

function InitTTest(x,y: double): TTest;
begin
  Result.a := x;
  Result.b := y;
end;
这项技术确实有效,并且消除了警告消息。我不喜欢这种方法,但是我不会使用它。高级记录没有继承性和类的其他特性,封装是它们的全部功能。所以我真的不喜欢在记录之外做这样的“工厂功能”


请记住以上只是一个“noob”的观点,在这里做了一些研究来回答我自己的问题。因此,如果我在上述任何方面都错了,我很高兴被纠正

是的,这就是构造函数的用途,以下使用FPC trunk编译,并且不生成警告:

{$mode delphi}

type TTest =
  record
    a,b: double;
    constructor Init(x,y: double);
  end;

constructor TTest.Init(x,y: double);
begin
  a := x;
  b := y;
end;


var t: TTest;
begin
  t.Init(0.1,0.2);
end.

从技术上讲,警告是正确的-您正在使用
t
,但它尚未初始化。编译器不知道您将要使用
Init
方法来设置记录(我想它可以解决这个问题,但对于更复杂的记录来说,似乎需要做很多工作)。我想这就是构造器的作用,但是我对FreePascal有点生疏,所以我不确定记录中是否有构造器(从技术角度来说)。谢谢Thomas。是的,我在使用类时总是使用构造函数,但不用于记录,因为它们不像类那样是动态“实例化”的。但你是对的,这些新记录可以有构造函数,所以我会尝试并报告回来。只是更新我的发现,我们使用构造函数。显然,Delphi允许记录有构造函数,但不允许FPC。我刚刚测试了将Init()从一个过程更改为一个构造函数,它给出了一条消息“错误:记录或记录帮助程序中不允许使用构造函数”。所以我想这不是答案。另一个更新:我能够在Delphi(D2009)上测试这一点,代码工作正常,没有发出警告。此外,D2009允许将此“setter”定义为过程或构造函数,尽管它的操作方式完全相同。FPC似乎不允许为记录使用构造函数(到目前为止)。因此,如果记录的数据字段是私有的,那么几乎没有办法解决这个问题。你需要使用一个“setter”过程来初始化它们,你只需要忍受这个警告。我使用的是FPC2.06(下载的FPC-2.6.2.i386-win32.exe),这对我来说绝对不起作用。正如我前面所说,我得到了一个错误:“错误:在记录或记录助手中不允许使用构造函数”,因此它甚至不会编译。什么是“FPC中继”,是像最新的“一夜之间”建立或什么。如果是这样,那么这个特性将在下一个稳定的版本中出现,对吗?还有一个问题。如果这将成为下一个稳定版本的一部分,那么在这里使用关键字“构造函数”而不是“过程”是否真的不会以任何方式改变它的操作方式?也就是所谓的“句法糖”。当我研究构造函数和记录的常规方法之间的区别时,这似乎是我迄今为止的一个故事。所以“构造函数”现在被允许,警告消息被抑制。但我只是想知道,即使您仍然使用过程而不是构造函数,警告消息也会被抑制吗?我只是想知道,因为Delphi(D2009)似乎对这两种方法都不关心。2.6.2是stable分支(2.6)中的最后一个stable。主干是来自不稳定(开发)分支的2.7.x。在一个肥胖的年头里可能会变成2.8,但首先是稳定的2.6.4。使用过程而不是构造函数时,会出现警告。FPC只是在警告和运行时检查方面更加严格。德尔福似乎已经忘记了它在这方面的根源。好的,谢谢马可。我现在正在设置答案,但我必须承认,我仍然不太喜欢像这样的简单记录的构造函数。首先,我认为构造函数应该只调用一次,而像我的Init()这样只设置值的东西可以在变量“生命周期”中多次调用。