Scala map/foreach 中的下划线 [英] Underscores in a Scala map/foreach

查看:35
本文介绍了Scala map/foreach 中的下划线的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你能帮我理解下划线在下面第二种情况下的作用吗?我猜它为列表的每个元素定义了一个匿名函数,但为什么不像第一种情况那样调用该函数?

Can you please help me understand what the underscore is doing in the second case below? I guess it's defining an anonymous function for each element of the list, but why is that function not being called like it is in the first case?

scala> List(1,2,3,4).foreach(x => println("*" * x))
*
**
***
****

scala> List(1,2,3,4).foreach(_ => println("*" * _))
$line25.$read$$iw$$iw$$iw$$iw$$$Lambda$1197/562203102@a632ae0
$line25.$read$$iw$$iw$$iw$$iw$$$Lambda$1197/562203102@a632ae0
$line25.$read$$iw$$iw$$iw$$iw$$$Lambda$1197/562203102@a632ae0
$line25.$read$$iw$$iw$$iw$$iw$$$Lambda$1197/562203102@a632ae0

推荐答案

正确的做法如下

List(1,2,3,4).map("*" * _).foreach(println)

scala 中有许多不同的下划线用例.我在这里列出了与这个问题相关的三个用例.

There are many different use cases for underscore in scala. I am listing three of those use cases that are relevant to this question here.

情况 1:在输入参数中使用下划线

当输入参数不会在 lambda 表达式的主体中使用时,您可以使用下划线作为 lambda 表达式的参数,因此您可以使用下划线作为占位符而不是将 lambda 表达式的输入参数声明为如下所示.List(1,2,3,4).foreach(_ => println("*" * 10))//这里显示 10 个 '*' 字符,与输入值无关.

You can use underscore for the argument of a lambda expression when the input argument is not going to used in the body of the lambda expression and thus you use the underscore as a placeholder instead of declaring a input argument for the lambda expression as shown below. List(1,2,3,4).foreach(_ => println("*" * 10)) // here 10 '*' characters are displayed irrespective of the input value.

情况 2:在 lambda 表达式主体中使用下划线.

当在 lambda 表达式的主体中使用下划线时,它指的是输入参数.如果输入只被引用一次,您可以以这种方式使用下划线.

when underscore is used in body of lambda expression it refers to the input argument. You can use the underscore in this fashion if the input is going to be referred only once.

例如:List(1,2,3,4).foreach(println("*" * _))//下划线将被输入参数替换.

情况 3:引用未应用的方法.

假设我有一个方法 foo(bar: Int).我可以通过表达式 foo _ (即 foo 紧跟一个下划线)来引用未应用的方法方法.此处未应用的函数意味着获取对函数对象的引用,该引用可在稍后按需执行.

lets say I have a method foo(bar: Int). I can refer to the unapplied method method by expression foo _ (ie foo immediately followed by an underscore). unapplied function here means getting a reference to a function object which can be executed later on demand.

@ def foo(bar: Int) = bar
defined function foo
@ val baz = foo _
baz: Int => Int = $sess.cmd24$$$Lambda$2592/612249759@73fbe2ce
@ baz.apply(10)
res25: Int = 10

您不能混合使用案例 1 和案例 2.即,您可以在输入参数或 lambda 函数体中使用下划线,但不能同时在两者中使用.由于您混合了这两种情况,因此您意外地使用了下划线用法的情况 3,如下所示.即您指的是通过 java.lang.String 上的隐式定义的未应用方法 *.

you cannot mix case 1 and case 2. ie you can use the underscore either in input argument or in the body of the lambda function but not in both. since you are mixing both the cases you are unexpectedly using case 3 of underscore usage as shown below. ie you are referring to the unapplied method * defined via implicits on java.lang.String.

@ "*" * _
res20: Int => String = $sess.cmd20$$$Lambda$2581/1546372166@20967474

如此有效地你正在做的事情如下所示.

so effectively what you are doing is something like the below.

List(1,2,3,4).foreach(x => println(("*" * _).toString))

这篇关于Scala map/foreach 中的下划线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆