在Scala中,使用``和使用命名标识符有什么区别?

在Scala中,使用``和使用命名标识符有什么区别?,scala,wildcard,Scala,Wildcard,为什么我在尝试使用\uuu而不是使用命名标识符时会出现错误 scala> res0 res25: List[Int] = List(1, 2, 3, 4, 5) scala> res0.map(_=>"item "+_.toString) <console>:6: error: missing parameter type for expanded function ((x$2) => "item ".$plus(x$2.toString))

为什么我在尝试使用
\uuu
而不是使用命名标识符时会出现错误

scala> res0
res25: List[Int] = List(1, 2, 3, 4, 5)

scala> res0.map(_=>"item "+_.toString)
<console>:6: error: missing parameter type for expanded function ((x$2) => "item
 ".$plus(x$2.toString))
       res0.map(_=>"item "+_.toString)
                           ^

scala> res0.map(i=>"item "+i.toString)
res29: List[java.lang.String] = List(item 1, item 2, item 3, item 4, item 5)
scala>res0
res25:List[Int]=List(1,2,3,4,5)
scala>res0.map(=>“项”+u.toString)
:6:错误:缺少扩展函数((x$2)=>”项的参数类型
“$plus(x$2.toString))
res0.map(=>“项”+0.toString)
^
scala>res0.map(i=>item+i.toString)
res29:List[java.lang.String]=列表(项目1、项目2、项目3、项目4、项目5)

如果您不打算绑定标识符,只需将该部分略去即可

res0.map("item "+_.toString)

用来代替变量名的下划线是特殊的;第n个下划线表示匿名函数的第n个参数。因此,以下是等效的:

List(1, 2, 3).map(x => x + 1)

List(1, 2, 3).map(_ + 1)
但是,如果您这样做:

List(1, 2, 3).map(_ => _ + 1) 
然后,您将使用一个函数映射列表,该函数忽略其单个参数,并返回由
\uu1
定义的函数。(此特定示例无法编译,因为编译器无法推断第二个下划线的类型。)具有命名参数的等效示例如下所示:

List(1, 2, 3).map(x => { y => y + 1 })

简言之,在函数的参数列表中使用下划线意味着“我忽略了函数体中的这些参数”。在函数体中使用下划线意味着“编译器,请为我生成一个参数列表”。这两种用法混合得不太好。

为了补充其他答案,以下是一些示例,说明为什么您会得到在某些情况下,将“\u1”用作占位符参数时会出现“缺少参数类型”

Scala的类型推断根据上下文考虑表达式的“预期”类型。如果没有上下文,则无法推断参数的类型。请注意,在错误消息中,
\uuu
的第一个和第二个实例将替换为编译器生成的标识符
x$1
x$2

scala> _ + _
<console>:5: error: missing parameter type for expanded function ((x$1, x$2) => x$1.$plus(x$2))
       _ + _
       ^
<console>:5: error: missing parameter type for expanded function ((x$1: <error>, x$2) => x$1.$plus(x$2))
       _ + _
           ^
但是,如果我们要求编译器推断类型参数,如果失败:

scala> bar(1, 1, _ + _)          
<console>:7: error: missing parameter type for expanded function ((x$1, x$2) => x$1.$plus(x$2))
       bar(1, 1, _ + _)
                 ^
<console>:7: error: missing parameter type for expanded function ((x$1: <error>, x$2) => x$1.$plus(x$2))
       bar(1, 1, _ + _)
                     ^

@Scoobie只是为了强调这一点,下划线在Scala中被用于许多不同的用途。正如David所解释的,在您的示例中,每种用法实际上都有不同的含义。还有其他含义——在Scala中,下划线是一个很好的例子,说明了运算符重载引起的问题。虽然我一开始对它有问题,但我可以estly说我从来没有想过要改进它。
scala> (_: Int) + (_: Int)          
res4: (Int, Int) => Int = <function2>
scala> def bar[A, R](a1: A, a2: A, f: (A, A) => R) = f(a1, a2)  
bar: [A,R](a1: A,a2: A,f: (A, A) => R)R

scala> bar[Int, Int](1, 1, _ + _)
res5: Int = 2
scala> bar(1, 1, _ + _)          
<console>:7: error: missing parameter type for expanded function ((x$1, x$2) => x$1.$plus(x$2))
       bar(1, 1, _ + _)
                 ^
<console>:7: error: missing parameter type for expanded function ((x$1: <error>, x$2) => x$1.$plus(x$2))
       bar(1, 1, _ + _)
                     ^
scala> def foo[A, R](a1: A, a2: A)(f: (A, A) => R) = f(a1, a2) 
foo: [A,R](a1: A,a2: A)(f: (A, A) => R)R

scala> foo[Int, Int](1, 1) { _ + _ }
res1: Int = 2

scala> foo(1, 1) { _ + _ }
res0: Int = 2