CnPack Forum


 
Subject: 如何将一个函数或者过程作为参数传给另一个函数
skyjacker
版主
Rank: 7Rank: 7Rank: 7
茶农


UID 2239
Digest Posts 9
Credits 617
Posts 269
点点分 617
Reading Access 100
Registered 2006-6-8
Status Offline
Post at 2007-6-15 10:58  Profile | Blog | P.M.  | QQ
如何将一个函数或者过程作为参数传给另一个函数

function,procedure 学习(1): 如何将一个函数或者过程作为参数传给另一个函数

原文:http://delphi.about.com/od/adptips2006/qt/functionasparam.htm
翻译: SkyJacker
时间: 2007.06.15
发布: Http://bbs.cnpack.org

如何将一个函数或者过程作为参数传给另一个函数

在 Delphi 中,过程类型(函数指针) 允许将一个过程或函数作为值赋给变量或者作为参数传递给其他过程和函数。
下面将介绍如何将 function (或 procedure) 作为另一个 function(或 procedure) 的参数进行调用。

步骤如下:

   1. 声明要作为参数的 function (或 procedure)。比如下面例子中的 "TFunctionParameter"

   2. 定义一个将其他 function 作为参数的 function。比如下面例子中的  "DynamicFunction"
  
    // 例子:
    type
       TFunctionParameter = function(const value : integer) : string;
    ...

    function One(const value : integer) : string;
    begin
       result := IntToStr(value) ;
    end;

    function Two(const value : integer) : string;
    begin
       result := IntToStr(2 * value) ;
    end;

    function DynamicFunction(f : TFunctionParameter) : string;
    begin
       result := f(2006) ;
    end;

    ...

    //用法:

    var
       s : string;
    begin
       s := DynamicFunction(One) ;
       ShowMessage(s) ; // 结果是 "2006"

       s := DynamicFunction(Two) ;
       ShowMessage(s) ; // 结果是 "4012"
    end;

注意:
    * 当然,你可以决定 TFunctionParameter 的类型。
      不管它是 procedure 还是 funtion,以及有多少个参数等等。

    * 如果 TFunctionParameter 是一个方法(一个对象实例的),则需要在过程类型声名中加上 of object , 比如:

      TFunctionParameter = function(const value : integer) : string of object;

    * 如果 f 参数可能被传入 nil, 则应该用 Assigned 函数检测一下。

    * 同时这也解决了编译错误 "Incompatible type: 'method pointer and regular procedure'"。



附英文原文:

How to Use a Function or a Procedure as a Parameter in another Function
Zarko Gajic,

In Delphi, procedural types (method pointers) allow you to treat procedures and functions as values
that can be assigned to variables or passed to other procedures and functions.

Here's how to call a function (or procedure) as a parameter of another function (or procedure) :

   1. Declare the function (or procedure) that will be used as a parameter.
      In the example below, this is "TFunctionParameter".
   2. Define a function that will accept another function as a parameter.
      In the example below this is "DynamicFunction"

    type
       TFunctionParameter = function(const value : integer) : string;

    ...

    function One(const value : integer) : string;
    begin
       result := IntToStr(value) ;
    end;

    function Two(const value : integer) : string;
    begin
       result := IntToStr(2 * value) ;
    end;

    function DynamicFunction(f : TFunctionParameter) : string;
    begin
       result := f(2006) ;
    end;

    ...

    //Example usage:

    var
       s : string;
    begin
       s := DynamicFunction(One) ;
       ShowMessage(s) ; //will display "2006"

       s := DynamicFunction(Two) ;
       ShowMessage(s) ; // will display "4012"
    end;

Note:

    * Of course, you decide on the signature of the "TFunctionParameter": whether it is a procedure or a function,
      how many parameters does it take, etc.

    * If "TFunctionParameter" is a method (of an instance object) you need to add the words of object to
      the procedural type name, as in:

      TFunctionParameter = function(const value : integer) : string of object;

    * If you expect "nil" to be specified as the "f" parameter, you should test for this using the Assigned function.

    * Fixing the "Incompatible type: 'method pointer and regular procedure'"




一壶清茶煮青春.
Top
Passion (LiuXiao)
管理员
Rank: 9Rank: 9Rank: 9


UID 359
Digest Posts 19
Credits 6760
Posts 3556
点点分 6760
Reading Access 102
Registered 2004-3-28
Status Offline
Post at 2007-6-15 11:21  Profile | Blog | P.M. 
从汇编的角度讲,只要将函数所在的地址,当作一个整型数据传过去就行了。
但从源码和类型的角度来讲,为了防止此函数被调用时出错,则需要严格规定这个函数的类型参数与调用方式。
Top
kendling (小冬)
高级版主
Rank: 8Rank: 8
MyvNet


Medal No.1  
UID 703
Digest Posts 5
Credits 978
Posts 580
点点分 978
Reading Access 101
Registered 2005-2-18
Location 广东
Status Offline
Post at 2007-6-16 11:39  Profile | Site | Blog | P.M.  | QQ | Yahoo!
哈哈,这个比较少用,不过我想,用来做功能统一入口可能挺不错。




小冬
http://MyvNet.com
Top
 




All times are GMT++8, the time now is 2024-4-29 05:31

    本论坛支付平台由支付宝提供
携手打造安全诚信的交易社区 Powered by Discuz! 5.0.0  © 2001-2006 Comsenz Inc.
Processed in 0.006399 second(s), 8 queries , Gzip enabled

Clear Cookies - Contact Us - CnPack Website - Archiver - WAP