Scala 2.8:匿名函数作为默认参数的类型推断
在 Scala 2.8.0 RC 2 中,此定义:
def buttonGroup[T](values: Array[T], textProvider: T => String = (t: T => t.toString)) = ...
给出错误消息:
未找到:值 t
def buttonGroup[T](values: Array[T], textProvider: T => String = (_.toString)) = ...
给出的
值扩展函数缺少参数类型 ((x$1) => x$1{}.toString{}){}
只有这个有效:
textProvider: T => String = (_:T).toString
为什么?
In Scala 2.8.0 RC 2 this definition:
def buttonGroup[T](values: Array[T], textProvider: T => String = (t: T => t.toString)) = ...
gives the error message:
not found: value t
def buttonGroup[T](values: Array[T], textProvider: T => String = (_.toString)) = ...
gives
missing parameter type for expanded function ((x$1) => x$1{}.toString{}){}
Only this works:
textProvider: T => String = (_:T).toString
Why?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这些都可以工作,无需类型注释:
但是为什么你的变体不起作用?
第一个实际上在任何上下文中都不是有效的 Scala:
第二个表达式
_.toString
使用匿名函数的占位符语法,并且仅在表达式具有预期类型时才有效。问题在于,其类型取决于类型参数的参数的默认表达式没有预期的类型。这似乎违反直觉,为什么它不将参数的声明类型作为预期类型?事实证明,表达式可以具有更具体的类型,并且类型检查被推迟到调用站点:
如果
textProvider
的类型不包含类型参数T,默认表达式有预期的类型,可以使用占位符语法:有关
命名参数和默认参数设计的详细说明,我推荐 Lucas Rytz 的 Scala Days 演示。
Either of these work, without type annotation:
But why don't your variations work?
The first one actually isn't valid Scala in any context:
The second expression
_.toString
uses the placeholder syntax for anonymous functions, and only works if the expression has an expected type.The problem is that the default expression for a parameter whose type depends an type parameter doesn't have an expected type. This seems counter-intuitive, why wouldn't it have the declared type of the argument as the expected type? It turns out that the expression can have a more specific type, and that type checking is deferred to the call-site:
If the type of
textProvider
doesn't include the type parameterT
, the default expression has an expected type, and you can use the placeholder syntax:For a detailed explanation of the design of named and default parameters, I recommend Lucas Rytz's Scala Days presentation.