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

查看:127
本文介绍了Scala地图/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)) // here 10 '*' characters are displayed irrespective of the input value.

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("*" * _)) // the underscore will be subsituted with the input argument.

情况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地图/foreach中的下划线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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