松开“分配给过程变量的本地过程/函数”优雅地限制
考虑以下测试用例:
{ CompilerVersion = 21 }
procedure Global();
procedure Local();
begin
end;
type
TProcedure = procedure ();
var
Proc: TProcedure;
begin
Proc := Local; { E2094 Local procedure/function 'Local' assigned to procedure variable }
end;
在第 13 行,编译器发出错误级别的消息,禁止此类本地过程使用的所有情况。 “官方”解决方案是将 Local
符号提升到外部范围(即:使其成为 Global
的同级),这会对代码“结构化”产生负面影响。
我正在寻找以最优雅的方式规避它的方法,最好是让编译器发出警告级别的消息。
Consider the following test-case:
{ CompilerVersion = 21 }
procedure Global();
procedure Local();
begin
end;
type
TProcedure = procedure ();
var
Proc: TProcedure;
begin
Proc := Local; { E2094 Local procedure/function 'Local' assigned to procedure variable }
end;
At line 13 compiler emits message with ERROR level, prohibiting all of the cases of such local procedures usage. "Official" resolution is to promote Local
symbol to the outer scope (ie: make it a sibling of Global
) which would have negative impact on code "structuredness".
I'm seeking the way to circumvent it in most graceful manner, preferably causing compiler to emit WARNING level message.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
最好的选择是使用新的匿名方法功能将其声明为
对过程的引用
,然后您可以很好地封装所有内容。这解决了 Mason 通过捕获匿名函数本地的任何变量来描述的问题。
Your best bet is to declare it as
reference to procedure
using the new anonymous methods feature and then you can keep everything nicely encapsulated.This gets around the issues that Mason describes by capturing any variables local to the anonymous function.
这就是为什么你不能这样做:
本地过程可以访问外部例程的变量范围。不过,这些变量是在堆栈上声明的,一旦外部过程返回,这些变量就会变得无效。
但是,如果您使用的是 CompilerVersion 21 (Delphi 2010),则您将获得 匿名方法可用,它应该能够执行您正在寻找的操作;你只需要稍微不同的语法。
Here's why you can't do it:
Local procedures have access to the outer routine's variable scope. Those variables are declared on the stack, though, and become invalid once the outer procedure returns.
However, if you're using CompilerVersion 21 (Delphi 2010), you've got anonymous methods available, which should be able to do what you're looking for; you just need a slightly different syntax.
如果确实需要在 D7 或更早版本中使用本地过程,可以使用此技巧:
但是问题是地址寄存器在不同的机器上可能有所不同 - 因此需要使用本地过程调用编写一些代码并通过断点查看哪些寄存器是在那里使用......
是的 - 在大多数实际生产情况下,这个技巧只是某种缓解措施。
If one really needs to use local procedures in D7 or earlier one could use this trick:
However the problem is that adress-registers could differ on different machines - so it's needed to write some code using local proc call and look via breakpoint which registers are used there...
And yeah - in most real production cases this trick is just some kind of palliative.
作为记录,我自制的闭包:
For the records, my homebrewn closure: