为什么scala无法推断映射的NodeSeq的类型?

时间:2016-07-28 14:28:00

标签: scala dictionary type-inference

我正在尝试从一组xml元素的id属性中提取id,但它失败并出现类型错误:

scala> (xml \\ "contentitem").map( (_ \ "@id").text )
<console>:14: error: missing parameter type for expanded function ((x$1) => x$1.$bslash("@id"))
       (xml \\ "contentitem").map( (_ \ "@id").text )
                                    ^

当我在地图中明确提供命名val(elem)时,它可以工作:

scala> (xml \\ "contentitem").map( elem => (elem \ "@id").text )
res8: scala.collection.immutable.Seq[String] = List(20761, 22798, 22799, 21167, 21438, 20770, 21480, 21906, 21907, 21923, 22766, 22771, 22794, 22800, 22803, 22804, 22818, 22819, 22820, 22821)

我不明白这里的区别。 elem_的区别如何?

2 个答案:

答案 0 :(得分:1)

当你写这样的东西时:

list map(_.toInt)

您直接告诉编译器您要映射list的元素。当你写:

(xml \\ "contentitem").map( elem => (elem \ "@id").text )

您告诉编译器您要采用elem并映射它,这与我之前的示例相同但更明确。但是,当你写:

(xml \\ "contentitem").map( (_ \ "@id").text )

你没有告诉它你想要隐式地(我的第一个例子)或明确地(你的第二个例子)使用集合的元素。相反,你告诉它采取任何_并提取id。

TLDR;它不能推断出类型。你没告诉编译器你想要什么。

答案 1 :(得分:1)

Scala正在寻找形成&#34;完成&#34;将占位符语法转换为匿名函数时的表达式。不要让我们看看你的例子:

(_ \ "@id").text

实际上包含了另一个完整的表达式:

_ \ "@id"

所以这个表达式转换为匿名函数:

x => x \ "@id"

然后在外表达式中用作:

(x => x \ "@id").text

现在在此表达式中无法推断x的类型,因此您的错误消息:

missing parameter type for expanded function ((x$1) => x$1.$bslash("@id"))

<强>更新

_不被视为完整表达式,因此代码.map(List(_))起作用,因为最内部的完整表达式为List(_),并且它将转换为x => List(x)

http://www.scala-lang.org/files/archive/spec/2.11/06-expressions.html#placeholder-syntax-for-anonymous-functions