_=> 这个下划线在 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);
【问题讨论】:
您好,欢迎来到 ***。我冒昧地稍微修改了您的问题,以增加您获得有用答案的机会,希望您不要介意。 请注意,假设list
是IEnumerable<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表达式语法
JAVA801_Lambda表达式的格式使用前提省略模式注意事项和匿名内部类的区别