我注意到不同的代码以不同的方式声明参数,我想知道是否有特定的理由这样做,或者是否是偏好。
说我写了这个函数(只是一个带有不同参数的例子)
function DoSomething(AHeight, AWidth: Integer; R: TRect): Boolean
begin
//
end;
如果声明如此,这有什么不同:
function DoSomething(var AHeight, AWidth: Integer; const R: TRect): Boolean
begin
//
end;
我知道变量是可读/可写的,常量是只读的,但是这样声明参数会如何产生影响呢?
对我来说,两个函数都在寻找调用代码来提供Height,Width和Rect,但是第二个函数看起来好像我们正在声明新的变量。
我有一种感觉,这将是一个如此直截了当的答案我觉得愚蠢但我必须知道有什么区别,如果有的话?
答案 0 :(得分:4)
documentation非常清楚地解释了这一点:
大多数参数都是值参数(默认值)或变量 (var)参数。值参数按值传递,而变量则传递 参数通过引用传递。要了解这意味着什么,请考虑一下 以下功能:
function DoubleByValue(X: Integer): Integer; // X is a value parameter begin X := X * 2; Result := X; end; function DoubleByRef(var X: Integer): Integer; // X is a variable parameter begin X := X * 2; Result := X; end;
这些函数返回相同的结果,但只返回第二个 - DoubleByRef可以更改传递给它的变量的值。假设 我们称这样的函数为:
var I, J, V, W: Integer; begin I := 4; V := 4; J := DoubleByValue(I); // J = 8, I = 4 W := DoubleByRef(V); // W = 8, V = 8 end;
执行此代码后,传递给的变量I DoubleByValue具有我们最初分配给它的相同值。但是 变量V,传递给DoubleByRef,具有不同的值。
值参数的作用类似于初始化为的局部变量 过程或函数调用中传递的值。如果你通过了 变量作为值参数,过程或函数创建一个 它的副本;对副本所做的更改对原始文件没有任何影响 变量并在程序执行返回调用者时丢失。
另一方面,变量参数就像指针一样 比副本。对a体内参数所做的更改 程序执行返回后,函数或过程仍然存在 调用者和参数名称本身已超出范围。
即使 相同的变量在两个或多个var参数中传递,没有副本 制作完成。以下示例说明了这一点:
procedure AddOne(var X, Y: Integer); begin X := X + 1; Y := Y + 1; end; var I: Integer; begin I := 1; AddOne(I, I); end;
执行此代码后,I的值为3。
我建议您在浏览器的书签中添加Delphi Language guide的链接。
答案 1 :(得分:2)
对问题here进行了很好的讨论,但基本上,没有var
,参数按值传递,而var
参数通过引用传递
当参数传递值时,参数的副本被复制,并且该复制被赋予该函数。对副本的任何更改都不会传播到单独的原始文件。
当参数通过引用传递时,该函数会被赋予对原始函数的引用,因此即使在进行调用之后,对副本的任何更改都将可见。
答案 2 :(得分:1)
参数可以是var,const,out和'none'
通常,函数可以更改参数,但不会更改调用参数。
var
x,y : Integer;
procedure Text(a: Integer);
begin
x := a;
a := 1;
end;
begin
x := 10;
y := 20;
Test(y);
// x = 20; y = 20;
end.
使用var参数时,更改会影响调用参数。
var
x,y : Integer;
procedure Text(var a: Integer);
begin
x := a;
a := 1;
end;
begin
x := 10;
y := 20;
Test(y);
// x = 20; y = 1;
end.
const参数,不能更改。
var
x,y : Integer;
procedure Text(const a: Integer);
begin
x := a;
a := 1; // ERROR!
end;
begin
x := 10;
y := 20;
Test(y);
// Does not compile
end.
仅写入out参数。
var
x,y : Integer;
procedure Text(out a: Integer);
begin
x := a;
a := 1;
end;
begin
x := 10;
y := 20;
Test(y);
// x = undefine y = 1;
end.