Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/mercurial/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala List.filter中的下划线_Scala - Fatal编程技术网

Scala List.filter中的下划线

Scala List.filter中的下划线,scala,Scala,这不起作用的原因: List(true,false).filter(_).size 错误显示: <console>:8: error: missing parameter type for expanded function ((x$1) => List(true, false).filter(x$1).size) List(true,false).filter(_).size ^ 我使用的是Scala 2.

这不起作用的原因:

List(true,false).filter(_).size
错误显示:

<console>:8: error: missing parameter type for expanded function 
((x$1) => List(true, false).filter(x$1).size)
    List(true,false).filter(_).size
                            ^

我使用的是Scala 2.9.0.1。

第一个错误是因为Scala不知道如何使用它。所以试试这个

List(true,false).filter(_:Boolean).size
之后,您将获得更多信息:

<console>:8: error: type mismatch;
found   : Boolean
required: (Boolean) => Boolean
 List(true,false).filter(_:Boolean).size

在Scala中处理
有点棘手,顺便说一句,我认为错误处理应该改进一点。回到主题,看一看这个例子:

def twice(i: Int) = i * 2
def gt2(j: Int) = j > 2

List(1,2,3) filter gt2
这可以很好地编译并按预期工作。但是,尝试组合函数时会出现神秘错误:

List(1,2,3) filter gt2(twice(_))

  error: missing parameter type for expanded function ((x$1) => twice(x$1))
          List(1,2,3) filter gt2(twice(_))
                                     ^ 
发生了什么事?基本上,当Scala编译器看到下划线时,它会将其绑定到最直接的上下文中,在本例中是
两次(41;
。这意味着我们现在使用函数
作为参数调用
gt2()
。编译器知道的是,这个函数接受一个参数并返回相同的类型。可以说,它应该计算出这个参数的类型,返回类型是基于
tweeps()
签名的
Int
,但是它暂时使用
x$1
占位符,直到他稍后计算出来

不幸的是,它无法做到这一点,因为当我们提供函数时,
gt2()
需要一个
Int
(至少编译器是这么认为的)

那么,为什么:

List(1,2,3) filter {k => gt2(twice(k))}
工作?编译器事先不知道
k
的类型。然而,它知道
gt2
返回
Boolean
,并期望
Int
。它还知道
tweeps()
需要
Int
并返回一个。这样它就推断出
k
的类型。另一方面,编译器从一开始就知道
filter
需要
Int=>Boolean


这是说回到你的情况。单独的下划线(<代码>(<)>代码>)不考虑“上下文”,因此编译器搜索另一个最直接的封闭上下文。
_
将被视为一个函数本身,以及
\u==true
。但不仅仅是下划线

那么,在这种情况下,最接近的直接上下文是什么(我相信它有一个科学名称…)?那么整个表达呢,

(x$1) => List(true, false).filter(x$1).size
编译器认为您正在尝试创建一个函数,该函数接受未知类型的参数并返回表达式类型的某些内容:
List(true,false).filter(x$1).size
。同样可以论证的是,它应该能够计算出
filter
接受
Boolean=>Boolean
并返回
Int
.size
),但显然它没有


那你能做什么呢?您必须给编译器一个提示,即下划线应该在较小的上下文中解释。你可以说:

List(true,false) filter (_ == true)
List(true,false) filter (i => i)
List(true,false) filter identity

我看到错误消息有了很大的改进!让我们看看您编写的错误消息以及您的工作版本:

((x$1) => List(true, false).filter(x$1).size)
          List(true,false).filter(a => a).size
或者,调整空格、括号和变量名:

a => List(true, false).filter(a     ).size
     List(true, false).filter(a => a).size
现在看起来一样吗


简单地说,当您传递下划线代替参数时,您正在执行以下操作。您可能更熟悉在匿名函数中用作参数占位符的下划线,这是它出现在表达式中时发生的情况,如
\uu1
。这两种用法是不同的,即使它们都导致匿名函数。

很好的解释。我可能不得不创建一些假帐户,以便对其进行多次投票。考虑到这种行为的许多问题,我认为编译器实际上最好不知道函数
(Boolean=>Boolean)=>Int
是否合适,但编译失败。另请参阅:
((x$1) => List(true, false).filter(x$1).size)
          List(true,false).filter(a => a).size
a => List(true, false).filter(a     ).size
     List(true, false).filter(a => a).size