在阅读了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))
我用:
- 为每个现有参数指定一个_
- 不使用任何内部匿名函数
括号有害吗?
说明如下:
关于"复杂的东西"的直觉是关于"语法类别Expr"的部分,而不是"简单Expr",您可以在语法部分复习一半。
你可以看到,里面的东西是表达式,所以这就是为什么人们近似的语法说,"它扩展到最里面的父级。"
通常可以通过使用中缀符号来避免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))
^
相当精确但不是很有帮助的答案是:"这是根据语言规范的适当行为"(注意:我实际上没有检查)
不那么精确,但更有帮助的是,第二个例子实际上要复杂得多。
在第一个例子中,你有一个函数(实际上是一个转换为函数的方法),它有一个未知类型的输入参数和一个未知类型的输出参数,必须与map的参数匹配(注意,有一些隐式参数你看不到,使得这个任务已经很重要了):
在第二个例子中你有一个
function + 0x100
,其结果传递给函数% 0x100
的结果被传递给一个函数Integer.toHexString
,虽然您不打算使用内部匿名函数(_ + 0x100),但实际上可能是一个。