Scala 模糊性与无括号函数调用
Posted
技术标签:
【中文标题】Scala 模糊性与无括号函数调用【英文标题】:Scala ambiguity with paren-less function calls 【发布时间】:2015-10-01 00:36:32 【问题描述】:请原谅长时间的设置。这个问题与Scala: ambiguous reference to overloaded definition - best disambiguation? 相关,但没有得到回答。
我对 Scala 还是很陌生,让我失望的一件事是 Scala:
具有一流的功能 在使用没有任何括号参数列表的对象点表示法时调用函数(就像函数是一个属性一样)这两种语言特性让我很困惑。看下面的代码:
我的班级 def something(in: String): String = 在 + "_X" 定义一些东西:字符串 => 字符串 = 案例_ =>“固定” val my = new MyClass() println(List("foo", "bar").map(my.something))我希望通过调用与map
所需的String => ?
参数匹配的something
原型来打印List("foo_X", "bar_X")
。相反,输出是List("Fixed", "Fixed")
- Scala 2.11 调用无参数something()
,然后将其返回值传递给map
。
如果我们注释掉 something
的第二个无参数原型,输出将变为预期结果,证明另一个原型在上下文中是有效的。
向第二个原型添加一个空参数列表(使其成为def something()
)也会改变行为。
将 my.something
更改为 my.something(_)
会使 Scala 意识到它之前默默忽略的模棱两可:
即使使用据说是为此目的的魔术尾随下划线也不起作用:
val myFun: (String) => String = my.something _这会导致:
错误:类型不匹配; 发现:()=>字符串=>字符串 必需:字符串 => 字符串 val myFun: (String) => String = my.something _我的问题:
如果我的MyClass
与所写的完全相同(原型没有更改,尤其是没有向其中一个原型添加空参数列表),我如何明确地告诉 Scala 我想要第一个单参数版本something
作为参数传递给另一个调用?
既然显然有两个令人满意的参数可以传递给 map
,为什么 Scala 编译器没有将歧义报告为错误?
有没有办法禁用 Scala 将 foo.bar
视为等同于 foo.bar()
的行为(有时,并非总是如此)?
【问题讨论】:
这在 Atomic Scala 中的“A Bit of Style”一章中进行了讨论。如果一个方法没有参数,它可以用括号定义,也可以不用括号。如果它是用括号定义的,则可以带或不带括号来调用它。但是,如果定义时不带括号,则只能在不带括号的情况下调用它。一个风格约定是如果调用它们会改变对象的内部状态,则使用括号定义方法,否则定义它们时不使用括号。在您设计的示例中,编译器似乎已尽力根据包括括号在内的签名选择正确的函数。 【参考方案1】:我已经在 Scala 问题跟踪器上提交了一个错误,并且共识似乎是这种行为是一个错误。编译器应该抛出一个关于“my.something”的模糊引用的错误。
【讨论】:
github.com/scala/bug/issues/9395 没有达成共识,但有回复。 Dotty 并不模棱两可,而是选择了方法。什么?以上是关于Scala 模糊性与无括号函数调用的主要内容,如果未能解决你的问题,请参考以下文章