如何从Delphi函数返回多个值
A most common construct in a application would be a . Known as routines, procedures or functions are statement blocks you call from different locations in a program.
应⽤程序中最常见的构造是 。 从程序中不同位置调⽤的语句块称为例程,过程或函数。
Simply put a procedure is a routine not returning a value while a function returns a value.
简单地说,过程是例程,函数返回值时不返回值。
A return value from a function is defined by the return type. In most cases you would write a function to return a single value that would be an integer, string, boolean or some other simple type, also return types could be an array, a string list, an instance of a custom object or alike.
函数的返回值由返回类型定义。 在⼤多数情况下,您将编写⼀个函数以返回单个值 ,该值可以是整数,字符串,布尔值或其他⼀些简单类型,返回类型也可以是数组,字符串列表,⾃定义对象的实例等。
Note that even if your function returns a string list (a collection of ) it still returns a single value: one instance of the string list.
请注意,即使你的函数返回⼀个字符串列表(集合 ),它仍会返回⼀个值:字符串列表中的⼀个实例。
Further, Delphi routines can really have many faces: Routine, Method, Method Pointer, Event Delegate,
此外,Delphi例程确实可以有很多⾯Kong:例程,⽅法,⽅法指针,事件委托,匿名⽅法...
函数可以返回多个值吗? ( Can a Function Return Multiple Values? )
The first answer that comes to mind is no, simply because when we think of a function, we think of a single return value.
我想到的第⼀个答案是不,仅仅是因为当我们想到⼀个函数时,我们想到的是⼀个单⼀的返回值。
Certainly, the answer to the above question is, however, yes. A function can return several values. Let's see how.
当然,上述问题的答案是肯定的。 ⼀个函数可以返回⼏个值。 让我们看看如何。
变量参数 ( Var Parameters )
How many values can the following function return, one or two?
以下函数可以返回多少个值,⼀个或两个?
function PositiveReciprocal(const valueIn : integer; var valueOut : real): boolean;
The function obviously returns a boolean value (true or false). How about the second parameter "valueOut" declared as a "VAR" (variable) parameter?
该函数显然返回⼀个布尔值(真或假)。 声明为“ VAR”(变量)参数的第⼆个参数“ valueOut”怎么样?
Var parameters are passed to the function by reference meaning that if the function changes the value of the parameter—a variable in the calling block of code—the function will change the value of the variable used for the parameter.
Var参数 通过引⽤传递给函数,这意味着如果函数更改参数的值(代码调⽤块中的变量),则函数将更改⽤于该参数的变量的值。
To see how the above works, here's the implementation:
要查看上述⼯作原理,请执⾏以下操作:
function PositiveReciprocal(const valueIn: integer; var valueOut: real): boolean;
begin
result := valueIn > 0;
if result then valueOut := 1 / valueIn;
end;
The "valueIn" is passed as a constant parameter—function cannot alter it, and it is treated as read-only.
“ valueIn”作为常量参数传递-函数⽆法更改它,并且将其视为只读。
If "valueIn" or greater than zero, the "valueOut" parameter is assigned the reciprocal value of "valueIn" and the result of the function is true. If valueIn is <= 0 then the function returns false and "valueOut" is not altered in any way.
如果“ valueIn”或⼤于零,则为“ valueOut”参数分配“ valueIn”的倒数,并且该函数的结果为true。 如果valueIn <= 0,则该函数返回false,并且“ valueOut”不会以任何⽅式更改。
Here's the usage:
write的返回值这是⽤法:
var
b : boolean;
r : real;
begin
r := 5;
b := PositiveReciprocal(1, r);
//here:
// b = true (since 1 >= 0)
// r = 0.2 (1/5)
r := 5;
b := PositiveReciprocal(-1, r);
//here:
// b = false (since -1
end;
Therefore, the PositiveReciprocal actually can "return" 2 values! Using var parameters you can have a routine return more than one value.
因此,PositiveReciprocal实际上可以“返回” 2个值! 使⽤var参数,您可以使例程返回多个值。
输出参数 ( Out Parameters )
There's another way to specify a by-reference parameter—using the "out" keyword, as in:
还有⼀种指定按引⽤参数的⽅法-使⽤“ out”关键字,如:
function PositiveReciprocalOut(const valueIn: integer; out valueOut: real): boolean;
begin
result := valueIn > 0;
if result then valueOut := 1 / valueIn;
end;
The implementation of PositiveReciprocalOut is the same as in PositiveReciprocal, there's only one difference: the "valueOut" is an OUT parameter.
PositiveReciprocalOut的实现与PositiveReciprocal中的实现相同,只有⼀个区别:“ valueOut”是OUT参数。
With parameters declared as "out", the initial value of the referenced variable "valueOut" is discarded.
对于声明为“ out”的参数,将丢弃引⽤变量“ valueOut”的初始值。
Here's the usage and the results:
这是⽤法和结果:
var
b : boolean;
r : real;
begin
r := 5;
b := PositiveReciprocalOut(1, r);
//here:
// b = true (since 1 >= 0)
// r = 0.2 (1/5)
r := 5;
b := PositiveReciprocalOut(-1, r);
//here:
// b = false (since -1
end;
Note how in the second call the value of the local variable "r" is set to "0". The value of "r" was set to 5 before the function call but since the parameter in declared as "out," when "r" reached the function the value was discarded and the default "empty" value was set for the parameter (0 for real type).
注意在第⼆个调⽤中如何将局部变量“ r”的值设置为“ 0”。 在函数调⽤之前,“ r”的值设置为5,但是由于参数in声明为“ out”,因此当“ r”到达函数时,该值将被丢弃,并且参数的默认“空”值被设置为(0对于实型)。
As a result, you can safely send uninitialized variables for out parameters—something that you should not do with "var" parameters. Parameters are used to send something to the routine, except here with "out" parameters :), and therefore uninitialized variables (used for VAR parameters) could have weird values.
结果,您可以安全地为out参数发送未初始化的变量,这是您不应该使⽤“ var”参数执⾏的操作。 参数⽤于将某些内容发送到例程,但此处带有“ out”参数:)除外,因此未初始化的变量(⽤于VAR参数)可能具有怪异的值。
返回记录? ( Returning Records? )
The above implementations where a function would return more than one value are not nice. The function actually returns a single value, but also returns, better to say alters, the values of the var/out parameters.
在上⾯的实现中,⼀个函数将返回多个值是不好的。 该函数实际上返回⼀个值,但也可以返回var / out参数的值,更好的说就是alter。
Because of this, you may very rarely want to use by-reference parameters. If more results from a function are required, you can have a function return a variable.
因此,您可能很少要使⽤按引⽤参数。 如果需要函数的更多结果,则可以让函数返回变量。
Consider the following:
考虑以下:
type
TLatitudeLongitude = record
Latitude: real;
Longitude: real;
end;
and a hypothetical function:
并假设⼀个功能:
function WhereAmI(const townName : string) : TLatitudeLongitude;
The function WhereAmI would return the for a given town (city, area, ...).
函数WhereAmI将返回给定城镇(城市,区域,...)的 。
The implementation would be:
实现将是:
function WhereAmI(const townName: string): TLatitudeLongitude;
begin//use some service to locate "townName", then assign function result:
result.Latitude := 45.54;
result.Longitude := 18.71;