_=> 这个下划线在 Lambda 表达式中是啥意思?

Posted

技术标签:

【中文标题】_=> 这个下划线在 Lambda 表达式中是啥意思?【英文标题】:_=> what does this underscore mean in Lambda expressions?_=> 这个下划线在 Lambda 表达式中是什么意思? 【发布时间】:2011-02-16 05:27:34 【问题描述】:

_=> expr 这样的 lambda 表达式是什么意思?

_ 作为 lambda 的输入的目的是什么?

例子:

int count = 0;
list.ForEach(_ => count += 1);

【问题讨论】:

您好,欢迎来到 ***。我冒昧地稍微修改了您的问题,以增加您获得有用答案的机会,希望您不要介意。 请注意,假设listIEnumerable<T>,他们可能(并且应该)刚刚使用了sum = list.Count(); 我想这可以用来防止你用一个新的变量名“污染”范围,这个新变量名可能会在其他地方使用而导致冲突。 【参考方案1】:

这是您不关心参数时使用的约定。

【讨论】:

在 Haskell 和其他函数式语言中更常见。我想这就是它的来源。 在 Haskell、ML、Scala 等中,_ 是模式匹配中的通配符。它基本上意味着“我不在乎,我总是希望这个匹配”。当涉及到命名你不关心的东西时,这种“我不在乎”会被延续,并从那里溢出到其他编程语言中。例如,它在 Ruby 中也用于表示与此示例中相同的含义,尽管 _ 在 Ruby 中绝对没有特殊意义。 @JörgWMittag 在 2010 年 5 月是正确的,但在 2010 年 6 月是正确的。真棒时机! :) ***.com/q/6397078/38765【参考方案2】:

它是一个参数名称,虽然不是一个有用的名称,但是当您需要指定表达式 具有 一个参数以获取代码时,它是通常使用的名称(根据某些约定)编译,但你并不真正关心它,所以你会忽略它。

它基本上是利用 C# 中合法标识符的语法构成,并且由于标识符可以以下划线开头,并且不包含任何其他内容,因此它只是一个参数名称。

你可以很容易地写出来:

var _ = 10;

【讨论】:

可以用 () 代替 _ 吗? 你试过用那个吗? 是的,我在使用 lambda 表达式创建线程时使用过它。 Thread t= new Thread(()=>doSomething(x,y)); t.start(); 我的假设是,使用 _ 是将集合的每个变量传递给 lambda 表达式,即使它没有被使用。但是当我们使用 () 时,它可能不会发生。我的意思是参数少 lambda。 您需要使用 ForEach 方法调用进行尝试。 Thread 构造函数有一个重载,它接受一个不接受任何参数的委托。尝试调用一个方法,比如 ForEach,它接受一个接受参数的委托。【参考方案3】:

_ 是一个有效的变量名。他们只是使用_ 作为变量。

【讨论】:

【参考方案4】:

因为 lamda 表达式主要用在简短的匿名代码中,因此有时不需要变量的名称,即使他们在代码块中不使用变量,所以他们只是给一个简短的 _,约定

【讨论】:

【参考方案5】:

我还支持将 _ => _.method() 用于单行方法调用 lambda,因为它减少了指令的认知权重。特别是在使用泛型时,写x => x.method() 只是添加了“这是什么'x'?它是空间坐标吗?”的瞬间考虑。

考虑以下情况:

Initialize<Client> ( _=>_.Init() );

与泛型调用一起使用,在这种情况下,下划线用作“绕过符号”。它避免了冗余,定义参数的类型是显而易见的并且可以从使用中推断出来——就像你使用 'var' 来防止重复类型声明一样。在这里写client=>client.Init() 只会使指令更长而不会增加任何意义。

显然,这不适用于要传递给方法的参数,该方法应以描述性方式命名。例如:Do( id=>Log(id) );

当使用代码块而不是单行代码时,方法调用的单下划线参数的使用几乎是不合理的,因为 lambda 标识符与其泛型定义断开了连接。一般来说,当要重复使用相同的标识符时,给它一个描述性的名称。

最重要的是,冗长只是为了消除歧义,特别是对于 lambdas,它最初是为了简化匿名委托的创建而创建的。无论如何,应该使用常识,平衡易读性和简洁性。如果符号只是真正功能的“钩子”,那么一个字符标识符就很好了。 For 循环和“i”和“j”字母作为索引器就是这种情况。

【讨论】:

这种方法+1!我虽然是唯一一个在 lambdas 中使用下划线来“减少认知权重”的人,而不是为了表明没有使用这个参数。使用下划线确实更容易阅读,特别是如果有很多链接并且您可以立即推断类型,就像 LINQ 查询的情况一样! Do(id => Log(id)) 最好缩写为Do(Log)

以上是关于_=> 这个下划线在 Lambda 表达式中是啥意思?的主要内容,如果未能解决你的问题,请参考以下文章

[技术分享] 20171209_java8新特性_lambda表达式语法

Java中Lambda表达式基础及使用详解

JAVA801_Lambda表达式的格式使用前提省略模式注意事项和匿名内部类的区别

09_Lambda表达式的遍历

为什么这个lambda表达式在语句中不起作用,但在方法中工作?

Python_00_lambda表达式