参数的占位符语法限制

时间:2014-07-11 12:57:35

标签: scala

在阅读了Scala编程书并稍微搜索之后,我仍然不明白为什么会这样:

val x = Array[Byte](1, 2, 3)
x.map{Integer.toHexString(_)}

而另一个稍微复杂一点的不是:

val x = Array[Byte](1, 2, 3)
x.map{Integer.toHexString((_ + 0x100) % 0x100)}

这个更长的选择确实有效:

x.map{b => Integer.toHexString((b + 0x100) % 0x100)}

这是我得到的模糊错误消息:

error: missing parameter type for expanded function ((x$1) => x$1.$plus(256))

我正在使用:

  • 每个现有参数
  • 正好一个_
  • 不使用任何内部匿名函数。

括号是否有害?

2 个答案:

答案 0 :(得分:3)

规范是this section

“复杂的东西”的直觉是关于“语法类别Expr”,而不是“SimpleExpr”,您可以查看about half-way through the syntax section

你可以看到parens中的东西是Exprs,所以这就是为什么人们通过说“它扩展到最内层的parens”来近似语法。

您通常可以通过使用中缀表示法来避免产生Expr。但是你的运营商优先权必须有所帮助。

scala> (1 to 5) map ("x" * _)
res1: scala.collection.immutable.IndexedSeq[String] = Vector(x, xx, xxx, xxxx, xxxxx)

scala> (1 to 5) map ("x".*(_))
res2: scala.collection.immutable.IndexedSeq[String] = Vector(x, xx, xxx, xxxx, xxxxx)

scala> (1 to 5) map ("x".*(_ + 5))
<console>:8: error: missing parameter type for expanded function ((x$1) => x$1.$plus(5))
              (1 to 5) map ("x".*(_ + 5))
                                  ^

scala> (1 to 5) map ("x" * _ + 5)
res5: scala.collection.immutable.IndexedSeq[String] = Vector(x5, xx5, xxx5, xxxx5, xxxxx5)

与:比较:

scala> (1 to 5) map ("abcdefg" apply _)
res8: scala.collection.immutable.IndexedSeq[Char] = Vector(b, c, d, e, f)

scala> (1 to 5) map ("abcdefg" apply _ + 1)
res9: scala.collection.immutable.IndexedSeq[Char] = Vector(c, d, e, f, g)

scala> (1 to 5) map ("abcdefg".apply(_ + 1))
<console>:8: error: missing parameter type for expanded function ((x$1) => x$1.$plus(1))
              (1 to 5) map ("abcdefg".apply(_ + 1))
                                            ^

scala> (1 to 5) map ("abcdefg"(_ + 1))
<console>:8: error: missing parameter type for expanded function ((x$1) => x$1.$plus(1))
              (1 to 5) map ("abcdefg"(_ + 1))
                                      ^

答案 1 :(得分:2)

相当精确但不是很有用的答案是:&#34;根据the Language Specification&#34;这是适当的行为。 (注意:我没有真正检查过)

不太精确,但更有帮助的可能是洞察力,第二个例子实际上更复杂。

在第一个示例中,您有一个函数(实际上是一个转换为函数的方法),其中一个输入参数为未知类型,输出参数为未知类型,必须与map的参数匹配(注意有一些隐含的论据你不明白,这个任务已经非常重要了):

在第二个例子中,你有一个

功能+ 0x100

将结果传递给函数%0x100

将结果传递给函数Integer.toHexString

虽然你不打算使用内部匿名函数(_ + 0x100),但实际上可能是一个。编译器无法确定。