在Delphi prism中,我们可以声明仅在特殊情况下需要的变量。
例如: 在棱镜中
If acondition then
begin
var a :Integer;
end;
a := 3; //this line will produce error. because a will be created only when the condition is true
这里'a'不能与3分配,因为它嵌套在分支内。 我们如何声明一个只能在delphi win32中的分支内部使用的变量。所以我可以减少内存使用量,因为只有在某个条件成立时才会创建它;
如果减少内存使用量不是问题我们有什么缺点(或者我们没有)
答案 0 :(得分:8)
你的问题的前提是错误的。您假设在允许块级变量的语言中,当控制进入或离开这些变量的范围时,程序会为这些变量分配和释放内存。因此,例如,您认为当acondition
为真时,程序会调整堆栈,以便在a
变量进入该块时腾出空间。但你错了。
编译器计算所有声明的变量和临时变量所需的最大空间,然后在进入函数时保留那么多空间。分配该空间就像调整堆栈指针一样简单;所需时间通常与预留的空间量无关。最重要的是,你的想法实际上不会节省任何空间。
拥有块级变量的真正好处是它们的范围有限。
如果您确实需要某些变量仅在一个代码分支中有效,那么请将该分支分解为单独的函数并将变量放在那里。
答案 1 :(得分:7)
Delphi不支持Java中的局部变量声明语句的概念,但您可以声明一个子过程:
procedure foo(const acondition: boolean);
procedure subFoo;
var
a: integer;
begin
a := 3;
end;
begin
If acondition then
begin
subFoo;
end;
end;
答案 2 :(得分:3)
Delphi中没有办法将变量的范围限制为小于整个例程。在单个整数变量的情况下,担心它是没有意义的......但是在大数据结构的情况下,你应该动态分配它,而不是静态分配,即代替
var integers: array[1..10000]of Integer;
使用
type TIntArray: array of Integer;
var integers: TIntArray;
If acondition then
begin
SetLength(integers, 10000);
...
end;
答案 3 :(得分:3)
您可以使用(dreaded)with
语句以及返回记录的函数来模拟块级变量。这是一些示例代码,用浏览器编写:
type TIntegerA = record
A: Integer;
end;
function varAInteger: TIntegerA;
begin
Result.A := 0;
end;
// Code using this pseudo-local-variable
if Condition then
with varAInteger do
begin
A := 7; // Works.
end
else
begin
A := 3; // Error, the compiler doesn't know who A is
end;
请注意,这种魔法并不能真正替代真正的块级变量:即使是那些可能在堆栈上分配的那些,就像大多数其他局部变量一样,编译器也不适合对待它们。它不会进行相同的优化:返回的记录将始终存储在实际的内存位置,而真正的本地变量可能与CPU寄存器相关联。编译器也不允许你将这些变量用于"for"
语句,这是一个很大的问题。
答案 4 :(得分:3)
要注意它只能是“语法糖”。编译器可能会确保您不使用内部作用域之外的变量,但这并不意味着它可以节省内存。无论如何,无论是否实际使用,该变量都可以在过程条目代码中分配在堆栈上。 AFAIK大多数ABI在进入时初始化堆栈并在退出时清理它。在执行函数时以更复杂的方式操作堆栈(包括处理不同的执行路径)可能性能更差 - 而不是单个指令来保留堆栈空间,您需要在代码中分散多个指令,并确保堆栈已恢复正确添加更多,特别是由于异常导致的堆栈展开可能会变得更加复杂。 如果目的是编写“更好”的代码,因为更好的范围处理,以确保错误的地方没有使用错误的变量,它可能是有用的,但如果你需要它作为一种节省内存的方法,它可能不是正确的方法
答案 5 :(得分:2)
评论了所有这些 - 德尔福有一个派对技巧,它比简单的局部变量有更多的用途,可以实现你的目标:
function Something: Integer;
begin
// don't want any too long local variables...
If acondition then
asm
// now I have lots of 'local' variables available in the registers
mov EAX, @AnotherVariable //you can use pascal local variables too!
// do something with the number 3
Add EAX, 3
mov @Result, EAX
jmp @next
@AnotherVariable: dd 10
@next:
end;
end;
end;
:))一点毫无意义的例子......