公开的函数把函数作为参数

如果想公开把其他的函数作为参数的函数,最好的方法是用委托(delegate)。考虑下面的例子,定义了两个函数,一个是公开函数,另一个把函数公开为委托。

module Strangelights.DemoModuleopen System

/// a function that provides filtering

let filterStringList f ra =

ra |>Seq.filter f

// another function that provides filtering

let filterStringListDelegate (pred:Predicate<string>) ra =

let f x =pred.Invoke(x)

newResizeArray<string>(ra |> Seq.filter f)

虽然,filterStringList 要比 filterStringListDelegate 短很多,但是,库用户会感谢你为把函数公开为委托而付出的努力。当从 C# 中调用这个函数时,就能更加清晰地体会到为什么这样。

下面的例子演示了调用filterStringList。调用这个函数,你需要创建委托,然后,使用FuncConvert 类把它转换成FastFunc,这是一种 F# 类型,用来表示函数值。对于库用户来说,还有一件相当讨厌的事情,需要依赖于FSharp.Core.dll,而用户可能并不想用它。

// !!! C# Source !!!

using System;

usingSystem.Collections.Generic;

usingStrangelights;

usingMicrosoft.FSharp.Core;

class MapOneClass{

public
static void MapOne() {

// define a list of names

List<string> names =
new List<string>(

new
string[] { "Stefany",
"Oussama",

"Sebastien",
"Frederik"});

// define a predicate delegate/function

Converter<string,
bool> pred =

delegate(string s) {return s.StartsWith("S");};

// convert to a FastFunc

FastFunc<string,
bool> ff =

FuncConvert.ToFastFunc<string,bool>(pred);

// call the F# demo function

IEnumerable<string> results =

DemoModule.filterStringList(ff, names);

// write the results to the console

foreach (var name
inresults) {

Console.WriteLine(name);

}

}

}

示例的运行结果如下:

Stefany

Sebastien

现在,把它与调用filterStringListDelegate 函数进行对比,在下面的例子中展示。因为已经使用了委托,就可以使用 C# 的匿名委托功能,并把委托直接嵌入函数调用中,减少了库用户的工作量,且不需要对FSharp.Core.dll 的编译时依赖。

// !!! C# Source !!!

using System;

usingSystem.Collections.Generic;

usingStrangelights;

class MapTwoClass{

public
static void MapTwo() {

// define a list of names

List<string> names =
new List<string>(

new
string[] { "Aurelie",
"Fabrice",

"Ibrahima",
"Lionel"});

// call the F# demo function passing in an

// anonymous delegate

List<string> results =

DemoModule.filterStringListDelegate(

delegate(string s) {return s.StartsWith("A");}, names);

// write the results to the console

foreach (var s
inresults) {

Console.WriteLine(s);

}

}

}

示例的运行结果如下:

Aurelie

公开的函数把函数作为参数

时间: 2024-12-18 13:25:59

公开的函数把函数作为参数的相关文章

SQL 自定义函数(Function)——参数默认值

sql server 自定义函数分为三种类型:标量函数(Scalar Function).内嵌表值函数(Inline Function).多声明表值函数(Multi-Statement Function) 标量函数:标量函数是对单一值操作,返回单一值. 内嵌表值函数:内嵌表值函数的功能相当于一个参数化的视图.它返回的是一个表,内联表值型函数没有由BEGIN-END 语句括起来的函数体. 多声明表值函数:它的返回值是一个表,但它和标量型函数一样有一个用BEGIN-END 语句括起来的函数体,返回值

以函数返回值做参数时,函数调用的顺序

环境:vs2013 在下面的代码中 1 //类似于下面的代码 2 3 foo(char*,char*,char*); 4 5 char* str ="A#B#C"; 6 7 foo(strtok(str,"#"),strtok(NULL,"#"),strtok(NULL,"#")); 预计让函数foo得到("A","B","C")的参数,程序编译的时候没问题,但是运行

python函数 位置参数,关键字参数,可变参数优先级

def fun(arg,args=1,*arg,**keywords): python 一共有这四类参数,第一类最常见,不用多说,第二类,关键字参数,python能通过关键字找到参数,python函数的这种特性使得函数参数更加灵活,不一定要按顺序来传,第三类:一个星号是将非关键字参数收集起来,以tuple的形式保存,第四类则必须要提供”传递参数名=传递参数值”形式传递参数. 至于怎么传,相信大家都知道,这里不多说. 要说明的是在python2中这四类参数传递时是有优先顺序的,不管是定义函数,还是

函数和过程的参数

函数和 过程的参数有: 1.常量参数,如 function addFun( const x,y:integer):integer; 函数里面的x,y的值不能改变 function addFun( const x,y:integer):integer; begin //x := x+1; //x,y在函数里面不能赋值,因为x,y为const; result := x+y; end; 2.形式参数,如 function addFun( x,y:integer):integer; 函数里面的x,y值可

王爽-汇编语言-综合研究五-函数接收不定量参数

(一) 研究目的 我们知道,在C语言中,函数是可以传递参数的.有些函数在声明是就定义了要传的参数的个数,比如我们定义void a(int i);这说明函数a只接受一个int型参数.而有些函数,比如print函数,是可以接收不定个数的参数的.那函数是怎样接收不定量参数的呢? (二) 研究过程 1) 有限个数的参数 首先我们来看程序是如何传参数的.我们编写一个程序,让他传递有限个参数: 我们编译链接,然后反汇编查看其代码: 我们看其代码,首先,在main函数中,分别将‘a’与2对应的ASCLL码放到

【转】深入理解C++的动态绑定和静态绑定 &amp; 不要重定义虚函数中的默认参数

为了支持c++的多态性,才用了动态绑定和静态绑定.理解他们的区别有助于更好的理解多态性,以及在编程的过程中避免犯错误.需要理解四个名词:1.对象的静态类型:对象在声明时采用的类型.是在编译期确定的.2.对象的动态类型:目前所指对象的类型.是在运行期决定的.对象的动态类型可以更改,但是静态类型无法更改.关于对象的静态类型和动态类型,看一个示例: class B { } class C : public B { } class D : public B { } D* pD = new D();//p

函数和函数参数

函数 函数是对程序逻辑进行结构化或过程化的一直编程方法.能将整块代码巧妙的隔离成易于管理的小块,把重复代码放到函数中而不是进行大量的拷贝--这样既能节省空间,也有助于保持一致性,因为你只需要改变单个的拷贝而无须去寻找再修改大量复制代码的拷贝. 创建函数 def语句 函数是用def语句来创建的,语法如下: def function_name(params): pass In [1]: def add(x,y): ...: print('{} + {} = {}'.format(x,y,x+y))

C/C++函数中使用可变参数

先说明可变参数是什么,先回顾一下C++里面的函数重载,如果重复给出如下声明: 1 int func(); 2 int func(int); 3 int func(float); 4 int func(int, int); 5 ... 这样在调用相同的函数名 func 的时候,编译器会自动识别入参列表的格式,从而调用相对应的函数体. 但这样的方法毕竟有限,试想一下我们假如想定义一个函数,我们在调用之前(在运行期之前)根本不知道我到底要调用几个参数,并且不知道这些参数是个什么类型,例如我们想定义一个

在虚函数的声明的参数列表后加上“=0”就将函数变成了纯虚函数

在虚函数的声明的参数列表后加上“=0”就将函数变成了纯虚函数class Base{ virtual void function()=0;}我们不需要为纯虚函数Base::function()提供任何定义,那些声明了纯虚函数的类就是抽象类.任何试图创建一个抽象类对象的操作都会导致编译器错误.如果一个派生Base并且重写了Base::function()函数,它就成为了具体的类.class Derived :public Basae { void function(); } 通常将抽象类用作接口声明