如何写出符合要求的Lambda表达式
本流程面向 刚知道Lambda的语法,被别人教一个需要回调函数的方法的Lambda函数,就只会这一个方法的写法,换一个需要回调函数的方法就没法写下去的新手。
本教程使用C#
编程语言,使用Visual Studio
作为代码编辑器。其他语言可以参考个思路。
如果你发现了本文中任何问题,烦请您在评论区留下自己的意见,我会及时修改。
跟着下面的流程走,你可以在 不了解这个需要回调函数的方法,不了解委托与泛型的概念的情况下,写出一个符合要求的 Lambda 表达式。
我们通过学习 Lambda 表达式后知道,Lambda 表达式由这几部分构成 :参数,方法体,以及返回值。
1 | (parameters) => { statement } |
Lambda的参数从何而来?
实际上使用 Lambda 表达式 作为回调函数时,其参数往往来自于委托,可以将鼠标放在需要回调函数的方法上,上面会提示参数列表,点击对应回调函数位置的参数类型,会跳转至对应的委托定义上,那边往往会给出参数的数量与类型以及返回值的类型。不了解委托没关系,只要你学过方法的定义,你就能找到返回值和参数列表的。
什么?参数类型是个T
?这我看鸡毛啊?
不要退缩,你只需要在跟着下面的流程走就可以了,从此处开始,你需要带着脑子,并开始上手跟着操作!
T
一般表示泛型,泛型泛型,也就是泛用的类型,和你的传入的其他参数的类型有关。
只看文字可能有些抽象,举个例子:
1 | // 要求使用Array.Find(),找出a数组中能被8整除的数 |
此时不确定 Array.Find()
里面要输入什么参数,就把鼠标放在 Find 上,会出现一个框框,最上面第一行显示了这些信息:
1 | T? Array.Find<T>(T[] array, Predicate<T> match) |
可以看到,出现了四次T
,这些T
代表的都是同一类型,也就是说,一旦确定了其中一个T
的准确类型,其他T
也要保持一致。
第一个 T?
:它所处位置正好是方法返回值的位置,代表的是Array.Find<T>()
这个方法的返回值类型,是 可空的任意类型。
第二个<T>
:声明 Array.Find<T>()
方法是一个泛型方法,并且 T
是该方法的类型参数,可以是任何类型。
第三个T[]
:表示类型 T
的数组,其中 T
是调用 Array.Find<T>()
时确定的类型。
第四个<T>
:这正好是我们所需要的回调函数的类型,Predicate<T>
是一个委托类型,接受一个 T
类型的参数并返回一个 bool
。
鼠标点击 Predicate<T>
,我们可以查看到这个委托的定义
1 | public delegate bool Predicate<in T>(T obj) |
参数类型还是T
!但是能确定的是,只有一个参数,并且返回值类型是 bool
。
回到我们的例子中,将int
数组a
放进Array.Find()
中,然后根据已知信息(只有一个参数,并且返回值类型是 bool
)便能写出一个完整的 Lambda 表达式了。
1 | int[] a = {2,4,124,23,4,32,1,42}; |
这时,把鼠标再次放到Find
上,会发现最上面那行的提示信息变了!
1 | int Array.Find<int>(int[] array,Predicate<int> match) |
所有的T
都变成了int
,这就说明,T
和参数a
数组有关
而 a
数组是 int[]
类型,对应的参数正是T[]
,因此,所有的T
都变成了int
。
Predicate<T>
的T
也变成了int
,也就是说,Predicate
的参数也从 (T obj)
变成了(int obj)
至此,我们确定了 Lambda 的 返回值为 bool 类型,只有一个参数,且参数为 int
类型。
而最后我们要确定的就是,我们 Lambda 的这个int
类型的参数item
代表着什么,Lambda 表达式的方法体要怎么写。
我们再次把鼠标放在Find()
上,在最上面那行提示中,点击Find
,查看Array.Find()
的源码。
1 | // Predicate<T> match 就是我们的 Lambda 表达式 |
不难看出,这个for
循环,是在遍历我们a
数组的所有元素
match(array[i])
在这里将此次循环对应的a数组的元素作为参数,去调用我们的Lambda
表达式,
从这里我们得出了目前缺失的构建 Lambda表达式 的两条信息之一,item
这个参数所代表的含义。item
也就是a
数组的一个元素。
match(array[i])
在每次循环中,将a
数组的一个元素作为参数,执行后返回一个布尔值,也就是 a
数组的这个元素,进入我们所写的 Lambda 表达式中,经过我们写的逻辑后,返回一个布尔值,表示是否满足了某种条件。如果满足该条件,Array.Find()
便返回这个元素。
回想我们调用Array.Find()
这个方法的初衷,是为了从a数组中寻找满足自己所要求的条件的元素
到这里,我们便可以确定,math()
应该是想让我们决定我们要寻找的元素需要符合什么样的条件,比如寻找开平方后等于16的元素,又比如寻找值为4的元素。
我们的要求是:找出a
数组中能被 8 整除的元素。
至此,我们得到最后一个 目前缺失的构建 Lambda表达式 的最后一条信息:Lambda 表达式的方法体要写什么。也就是要判断传入的a
数组的元素是否能被 8 整除;
现在我们便可以确定 Lambda 表达式最终的写法了!
1 | int[] a = {2,4,124,23,4,32,1,42}; |
到这里我们便完成了一次从 不知道Lambda表达式要怎么写 ,到完成一个 Lambda 表达式的过程。
如果你理解能力强,或者经过上面的步骤后,仍然无法确定符合要求的Lambda表达式该怎么写,可以把鼠标放在Find()
上,下面有一个GitHub 示例和文档
,点进去,去参考别人在使用这个方法时,是如何书写Lambda表达式的。
留一个作业来检验你的学习成果,或者说来熟悉上述的流程:
1 | // 使用 Array.Exists() 判断 s 数组中是否存在 “日之朝矣” 这个字符串 |
答案:
点击展开 查看答案
1 | // 使用 Array.Exist() 判断 s 数组中是否存在 “日之朝矣” 这个字符串 |
- 标题: 如何写出符合要求的Lambda表达式
- 作者: 日之朝矣
- 创建于 : 2024-07-27 22:28:53
- 更新于 : 2024-08-18 09:25:27
- 链接: https://blog.rzzy.fun/2024/07/27/write-Lambda-expressions-that-meet-the-requirements/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。