Scala:我什么时候需要在地图功能之前加一个点?

时间:2016-07-28 17:28:49

标签: scala

我认为集合和地图功能之间的点是可选的,但似乎故事还有更多。

这适用于两种格式:

protected override void OnKeyPress(KeyPressEventArgs e)
{
    base.OnKeyPress(e);

    // let digits and . go
    if(char.IsDigit(e.KeyChar) || (e.KeyChar == '.'))
        return;

    // all other chars are ignored,
    // you can add other stuff here if needed like
    // the minus sign, backspace etc
    e.Handled = true;
}

这失败了:

scala> List(1,2,3) map (_*2)
res6: List[Int] = List(2, 4, 6)

scala> List(1,2,3).map (_*2)
res7: List[Int] = List(2, 4, 6)

但这有效:

scala> articleFiles map (file => (file \\ "contentitem").map( a => (a \ "@id").text) ).flatten
<console>:17: error: missing parameter type
       articleFiles map (file => (file \\ "contentitem").map( a => (a \ "@id").text) ).flatten
                         ^

请注意,最后两个示例之间的唯一区别是scala> articleFiles.map (file => (file \\ "contentitem").map( a => (a \ "@id").text) ).flatten res7: 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, 20456, 20771, 21337, 21542, 21590, 20768, 20775,

中的点

3 个答案:

答案 0 :(得分:3)

您无法在一个链中混合使用.的呼叫,因此

articleFiles map (file => (file \\ "contentitem").map( a => (a \ "@id").text) ).flatten

装置

articleFiles.map((file => (file \\ "contentitem").map( a => (a \ "@id").text) ).flatten)

显然不起作用:函数没有flatten方法。发生此特定错误是因为匿名函数中的参数类型只能在预期函数类型的上下文中使用时才会被省略,而这不是这样的上下文。

答案 1 :(得分:3)

只是补充一点,有一些工具可以显示您的代码发生了什么,特别是推断了哪些parens和类型。

scala> val vs = (1 to 10).toList
vs: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

scala> vs.map(Option.apply)
res0: List[Option[Int]] = List(Some(1), Some(2), Some(3), Some(4), Some(5), Some(6), Some(7), Some(8), Some(9), Some(10))

scala> vs.map(Option.apply).flatten
res1: List[Int] = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

scala> vs map(Option.apply).flatten
<console>:13: error: missing argument list for method apply in object Option
Unapplied methods are only converted to functions when a function type is expected.
You can make this conversion explicit by writing `apply _` or `apply(_)` instead of `apply`.
       vs map(Option.apply).flatten
                     ^

scala> vs map(Option.apply(_)).flatten
<console>:13: error: missing parameter type for expanded function ((x$1: <error>) => Option.apply(x$1))
       vs map(Option.apply(_)).flatten
                           ^

scala> vs map(Option.apply(_)).flatten // show
[snip]
      val res4 = vs.map(((x$1) => Option apply x$1).flatten)

<console>:13: error: missing parameter type for expanded function ((x$1: <error>) => Option.apply(x$1))
       vs map(Option.apply(_)).flatten // show
                           ^

答案 2 :(得分:0)

在Scala中,运算符是方法,可以这样处理。我们可以使用句点来调用map作为方法,或者只是将其用作运算符。 This is a good explanation.
至于为什么第一个失败而第二个失败,第二个例子比第一个更不明确。编译器知道方法调用所期望的变量类型,但是通过操作符调用它更加模糊(可能是AnyVal),因此它会抛出缺少的参数类型。 简单地说,当堆叠映射并使用不同的调用时,编译器无法确定它应该使用哪种变量类型。