有人能解释一下这到底发生了什么吗?我现在还没有完全了解它:
val s = Seq(1D,2D,3D,4D)
case class WithUnit(value: Double, unit: String)
s map { WithUnit(_,"cm") } // works
s map { WithUnit(value = _ , unit = "cm") } // error: missing parameter type for expanded function ((x$2) => value = x$2)
我猜编译器无法推断参数类型,因为我写了参数的名称。但为什么不呢?仅仅因为陈述参数的名称应该更难吗?!
谢谢!
答案 0 :(得分:29)
当你写道:
WithUnit(value = _, unit = "cm")
你希望它意味着:
x => WithUnit(value = x, unit = "cm")
但如果仔细查看错误消息,您会看到编译器没有看到它,它将其解析为:
WithUnit(x => value = x, unit = "cm"})
正如您所看到的,_的范围比您想要的更紧密。
_总是选择最紧密的非退化范围。范围在语法分析期间纯粹由语法决定,而不考虑类型。
非退化,我的意思是编译器没有认为你的意思:
WithUnit(value = x => x, unit = "cm")
最严格的非简并范围是指最内层函数括号相对于下划线定义的范围。没有这样的规则,当嵌套函数调用时,编译器将无法知道哪个_对应于哪个函数。
答案 1 :(得分:3)
试试这个:
scala> val withUnits = s map { x => WithUnit(value = x, unit = "cm") }
withUnits: Seq[WithUnit] = List(WithUnit(1.0,cm), WithUnit(2.0,cm), WithUnit(3.0,cm), WithUnit(4.0,cm))
问题是使用下划线直接定义任何一个函数。
详细说明见chapter 8.5. Placeholder syntax in the "Programming in Scala" book。