【问题标题】:Why can't Scala infer the type of _?为什么 Scala 不能推断 _ 的类型?
【发布时间】:2013-12-22 03:59:59
【问题描述】:

我听说在 Scala 中我可以在匿名函数中使用 _ 作为“匿名参数”:

List(1,2,3).foreach(print(_))

但是这段代码无法编译:

scala> def a[T](s: Seq[T]): Seq[T] = s.map(_)
<console>:7: error: missing parameter type for expanded function ((x$1) => s.map(x$1))

这可以:

scala> def a[T](s: Seq[T]): Seq[T] = s.map(x => x)
a: [T](s: Seq[T])Seq[T]

这似乎与类型推断有关。但是x =&gt; x 怎么能提供比_ 更多的信息呢?

【问题讨论】:

    标签: scala type-inference


    【解决方案1】:

    这里的问题不是类型推断。

    从错误消息中可以看出,s.map(_) 的等效代码不是 s.map(x =&gt; x),而是:

    i => s.map(i)
    

    就像print(_)(实际上是Predef.print(_))表示i =&gt; Predef.print(i)

    或者像"a" + _ 表示"a".+(_) 表示s =&gt; "a".+(s)

    这在当前上下文中没有意义。

    假设您有一个函数列表String =&gt; String (fs),并且您想将所有这些函数应用于String 列表。您将使用以下代码:

    fs.map{f => s.map(f)}
    

    或者只是这个:

    fs.map{s.map(_)}
    

    补充:如果x =&gt; x,你可以使用identity 方法。它是默认导入的,但您可以使用附加导入使其更短:

    import Predef.{identity => id}
    List(1, 2, 3) map id
    // List[Int] = List(1, 2, 3)
    

    注意identity 是一个众所周知的名字,所以在团队中你应该使用它而不是你的别名。

    【讨论】:

    • +1 非常直观的占位符语法解释。
    【解决方案2】:

    这似乎与类型推断有关。但是 x => x 怎么能提供比 _ 更多的信息呢?

    x => x 是 Function1 的一种类型,这是 map 函数期望的参数。编译器无法推断出 T 类型的匿名变量 _ 真的是 Function1。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-06
      相关资源
      最近更新 更多