js 拉姆达表达式和function函数_lambda表达式可以用来声明


这篇依然是番外

本来以为委托事件的专题已经讲完了,甚至已经列好下一个专题的提纲——但最终还是觉得有必要用一篇小短文介绍一下Lambda表达式——一种和委托密切相关的语法机制

我自己学习C#的一开始就用上了Lambda表达式(在学习某个Unity案例的过程中 ),但完全看不懂是个什么东西,去查了官方文档也是一知半解,直到正式学习C#的第六个月才在刘铁锰老师的《C#入门详解》中最终弄懂

lambda是希腊字母“λ”的英语读音,也就是《半条命》的那个“入”,这个字母读作Lambda,拉姆达(但鬼才知道为什么这种语法要叫做“拉姆达表达式”


js 拉姆达表达式和function函数_泛型_02

半条命2宣传图,小时候以为这个字是中文的“入”....


Lambda表达式是什么?

这种表达式遵循以下语法:

(参数列表)=>{方法体}

其中“=>”就是Lambda操作符

一个完整的lambda表达式就是一个完整的方法,表达式本身就代表着这个方法的引用,可以被装进委托里

上面那句语法中,左边是方法的参数列表,右边则是方法体,而lambda操作符不妨解读为“将左边的参数列表代入到右边的方法体中”

例如,我们可以用Lambda表达式来声明一个简单的加法函数:


(int a, int b) => { return a + b; }


上面这句表达式翻译成中文就是“一个输出两个整型输入数之和的函数”,其意义等同于:


static int Add(int a, int b)
        {
            return a + b;
        }


PS:别忘了方法体的部分要加上分号表示语句结束了

Lambda表达式有什么用?

就我目前掌握的知识来看,主要有三种作用:

一:声明一个匿名方法

在上面的栗子里,用Lambda表达式声明的加法函数是匿名的,而用常规函数语法去写则必须有一个名字——栗子里是“Add”

匿名的声明方法有两个好处,首先是避免污染名称空间——只要声明了一个函数,函数名就永久存在于上下文环境里了(除非把这段代码删掉)

另外,对于某些很简单的,只是临时使用一下的小逻辑,专门声明方法再去调用会让代码变得臃肿(写起来也比较麻烦)

二:声明并调用一个inLine方法

所谓的InLine方法就是在调用处的语句直接声明的方法(区别于大部分先单独声明再调用的方法)——其实和上条结合起来就是,lambda表达式常用于匿名的声明并直接调用一个方法,以此使代码更加简洁(通常是简单的方法)

三:作为其它方法的实际参数参与运算

调用具有方法参数的方法时,除了使用委托实例,也可以直接把Lambda表达式作为实际参数传入——因为Lambda表达式本身就代表其所定义方法的引用

Lambda表达式怎么用?

大部分情况下,Lambda表达式需要通过委托实例来间接调用(你不能直接在Lambda表达式后面加上方法调用操作符“()”,编译器会报错的)

具体来说,我们先把这个表达式(或者说这个匿名方法)装进一个委托实例里:


Func<int,int,int>f1 = (int a, int b) => { return a + b; };


然后再调用这个委托实例来间接调用Lambda表达式:


Console.WriteLine(f1.Invoke(1,2));


输出当然是3

在将Lambda表达式作为实际参数使用时,直接把整个表达式复制到参数列表的相应位置就可以了,我们先声明一个有委托类型参数的方法:


static int LambdaTest(Func<int,int,int> func,int a,int b)
        {
            return func.Invoke(a,b);
        }


这个方法的参数有三个:Func<int,int,int>和int a以及int b

其中Func<int,int,int>的意思是“有两个int类型参数并返回一个int值的方法”,Func是.Net预设的一种泛型委托,如果看不懂这里可以回去看一下C#委托事件机制:委托的用法(3) - 褚星痕的文章 - 知乎 https://zhuanlan.zhihu.com/p/147242231

这里多嘴一句,所谓“泛型”就是“泛化的数据类型”,表现在这里就是Func<>委托尖括号里填写不同的数据类型时这个委托都能成立,关于泛型的知识我会在下篇专门来讲

然后,我们来用Lambda表达式作为实际参数调用这个方法:


static void Main(string[] args)
        {
            Console.WriteLine(LambdaTest((a,b)=> { return a + b; },1,2));
        }


输出当然依旧是3


至此,本专栏的第一个专题真正的结束了,感谢朋友们的支持,这么冷门的专栏居然有这么多朋友一直追更到现在,实在是不胜荣幸!