为什么不能在函数文字中为变量分配占位符? [英] Why can't a variable be assigned placeholder in function literal?

查看:39
本文介绍了为什么不能在函数文字中为变量分配占位符?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法理解函数文字中的下划线.

I'm having trouble understanding underscores in function literals.

val l = List(1,2,3,4,5)
l.filter(_ > 0)

工作正常

l.filter({_ > 0})

工作正常

l.filter({val x=1; 1+_+3 > 0}) // ie you can have multiple statements in your function literal and use the underscore not just in the first statement.

工作正常

然而:

l.filter({val x=_; x > 0})
e>:1: error: unbound placeholder parameter
l.filter({val x=_; x > 0})

我无法将 _ 分配给变量,即使以下是合法的函数文字:

I can't assign the _ to a variable, even though the following is legal function literal:

l.filter(y => {val x=y; x > 0})

工作正常.

什么给?我的val x=_"是否被解释为其他东西?谢谢!

What gives? Is my 'val x=_' getting interpreted as something else? Thanks!

推荐答案

实际上,您必须备份一个步骤.

Actually, you have to back up a step.

您误解了大括号的工作原理.

You are misunderstanding how the braces work.

scala> val is = (1 to 5).toList
is: List[Int] = List(1, 2, 3, 4, 5)

scala> is map ({ println("hi") ; 2 * _ })
hi
res2: List[Int] = List(2, 4, 6, 8, 10)

如果 println 是传递给 map 的函数的一部分,你会看到更多的问候.

If the println were part of the function passed to map, you'd see more greetings.

scala> is map (i => { println("hi") ; 2 * i })
hi
hi
hi
hi
hi
res3: List[Int] = List(2, 4, 6, 8, 10)

额外的大括号是一个块,它是一些语句后跟一个结果表达式.结果 expr 是函数.

Your extra braces are a block, which is some statements followed by a result expression. The result expr is the function.

一旦你意识到只有结果 expr 有一个预期类型是 map 预期的函数,你就不会想到在前面的语句中使用下划线,因为裸下划线需要预期的键入以明确下划线的含义.

Once you realize that only the result expr has an expected type that is the function expected by map, you wouldn't think to use underscore in the preceding statements, since a bare underscore needs the expected type to nail down what the underscore means.

这是类型系统告诉您下划线位置不正确.

That's the type system telling you that your underscore isn't in the right place.

附录:在您提出的评论中:

Appendix: in comments you ask:

如何使用下划线语法来绑定 a 的参数函数字面量到变量

how can I use the underscore syntax to bind the parameter of a function literal to a variable

这是一个愚蠢"的问题,请原谅这个表达吗?

Is this a "dumb" question, pardon the expression?

下划线是这样你不必命名参数,然后你说你想命名它.

The underscore is so you don't have to name the parameter, then you say you want to name it.

一个用例可能是:传入参数很少,但我只想命名其中一个.

One use case might be: there are few incoming parameters, but I'm interested in naming only one of them.

scala> (0/: 是)(_ + _)res10:整数 = 15

scala> (0 /: is)(_ + _) res10: Int = 15

scala> (0/: is) { case (acc, i) => acc + 2 * i }res11:整数 = 30

scala> (0 /: is) { case (acc, i) => acc + 2 * i } res11: Int = 30

这行不通,但人们可能想知道为什么.也就是说,我们知道折叠期望什么,我们想应用带有 arg 的东西.哪个arg?部分应用偏函数后剩下的任何东西.

This doesn't work, but one may wonder why. That is, we know what the fold expects, we want to apply something with an arg. Which arg? Whatever is left over after the partially applied partial function.

scala> (0/: is) (({ case (_, i) => _ + 2 * i })(_))

scala> (0 /: is) (({ case (_, i) => _ + 2 * i })(_))

scala> (0/: is) (({ case (_, i) => val d = 2 * i; _ + 2 * d })(_))

scala> (0 /: is) (({ case (_, i) => val d = 2 * i; _ + 2 * d })(_))

SLS 6.23匿名函数的占位符语法"提到了expr"边界,当你必须知道下划线代表什么时——它本身不是一个范围.如果你为下划线提供类型归属,它仍然会抱怨预期的类型,大概是因为类型推断是从左到右的.

SLS 6.23 "placeholder syntax for anonymous functions" mentions the "expr" boundary for when you must know what the underscore represents -- it's not a scope per se. If you supply type ascriptions for the underscores, it will still complain about the expected type, presumably because type inference goes left to right.

这篇关于为什么不能在函数文字中为变量分配占位符?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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