就是函数返回函数

时间:2022-03-26 07:33:02


何谓函数式编程

相信大家在实际的开发中,很多情况下完成一个成果都需要借助多个类,那么我们这里的根基单元就是类。而函数式编程则越发细化,致使我们解决一个成果的根基单元是函数,而不是类,每个成果都是由多个函数组成,并且函数之间没有直接的关系。如果简单的文字描述还不敷以让你理解,下面我们就配以图来演示。

如下图所示,图左是我们设计好的三个函数,而右边则是我们需要实现的成果。而我们需要做的就是操作这三个函数去完成对应的三个成果,笔者在这里只是进行简单而又形象的表述,实际的开发过程可能需要更多的函数,并且需要使用差此外函数式编程的方法组合才华完成对应的成果。

就是函数返回函数

后面我们假设F1和F2进行组合可以完告成能G1,那么功效就如下图所示:

就是函数返回函数

对应的其他成果我们依然是凭据上面的方法进行组合就可以完成对应的成果,这样做一定有其对应的长处,对笔者而言最大的长处就是函数不受外部环境的影响,这里我们不能与类中的要领相提并论,因为要领会受到类上下文变量的影响,出格是在多线程的情况下会呈现共享读和写的问题,而函数则不会,因为他只是通过参数的方法接收外部的变量,还有一点就是复用性很强,如果前期设计的丰裕,在后期开发过程中函数可以阐扬到最大的感化。说了这么多空话,下面我们就可以开始我们的函数式编程的第一部分――部分应用。


部分应用

列位不用被这个名词吓坏,他主要是将我们多个参数的函数进行拆分,拆成多个只有一个参数的函数,好比下面这个函数,我们正常写的话都是这样写的:


代码如下:


Func<int, int, int> Add = (x, y) => x + y;

怎么挪用相信笔者就不需要过多介绍了,下面我们就要让他能够撑持部分应用:


代码如下:


Func<int, Func<int, int>> Add = x => y => x + y;

这下就应该大白了吧,只是在接收了一个值之后返回了下一个函数,然后我们再挪用这个返回的函数就完成整个挪用,我们是不是部分使用了这个函数?所以叫部分应用。下面我们来看看怎么使用这个函数:


代码如下:


var Add2 = Add(2);

var result = Add2(4);

这样分成两行对照容易看懂,但是我们可以仅仅使用一行就可以了,好比下面这个方法:


代码如下:


var result = Add(2)(5);

哇,是不是瞬间觉得高大上了,如果我们这个要领的参数再多点,就是括号加括号,相信别人看到你这行代码后就会呵呵了,然后心里一万个“某某”马奔驰。

我去,看到这的人会可能会吹捧这又没有什么太特另外对象,就是函数返回函数。对就是函数返回函数,但是实际运用起来你就会发明舒畅多了,下面笔者简单的举一个对照靠谱的例子来说明部分应用能够带给我们什么,好比我们经常需要执行SQL语句,固然需要使用SqlConnection,然后附加上对应的SQL语句,为此我们可以开发一个简单的函数,用来简化这一过程:


代码如下:


Func<SqlConnection, Func<String, DataSet>> ExecSql = x => y =>

{

using (x)

{

x.Open();

var com = x.CreateCommand();

DataSet ds = new DataSet();

com.CommandText = y;

SqlDataAdapter adapter = new SqlDataAdapter(com);

adapter.Fill(ds);

return ds;

}

};

然后挪用起来就简单多了,我们只要通报给对应的SqlConnection东西,然后对应的返回值我们就可以用来执行我们的SQL语句了,具体的使用示例如下所示:


代码如下:


var esql = ExecSql(new SqlConnection(“xxx”));

var rds = esql(“select xxxx from xxx”);

rds = esql(“select ffff from ffff”);

但是做到这还没有结束,面对那些总是想出奇怪问题的人,我们还有一个需要做,,就是我们可能先要通报SQL语句,然后再通报对应的SqlConnection东西,没问题,我们专门为此写个函数:


代码如下:


Func<String, Func<SqlConnection, DataSet>> ExecSqlT = x => y => ExecSql(y)(x);

我们就继续该怎么挪用就挪用吧,但是上面都是从一开始就操作部分应用的方法来写,实际情况可能是已经写好的普通的方法,需要转换成部分应用的方法。那么下面我们可以本身先手动的写几个扩展,以便于以后的使用,首先我们来写存在两个参数和返回值的扩展:


代码如下: